'Spring JdbcTemplate rollback using annotations
I am new to Java and Spring. I am learning spring jdbc connectivity using JdbcTemplate. I wrote the below code.
Controller
service.importInsuranceEstimates(insuranceEstimates);
Service class
public void importInsuranceEstimates(List<String[]> insuranceEstimates) {
for (String[] insuranceEstimate: insuranceEstimates) {
repository.insertInsuranceEstimate(insuranceEstimate);
}
}
Repository class
public void insertInsuranceEstimate(String[] insuranceEstimate) {
jdbcTemplate.update("insert into some_table values (?, ?, ?)", insuranceEstimate[0], insuranceEstimate[1], insuranceEstimate[2]);
}
Assume that after inserting few records, the next insert statement failed. In this case, I would like the previously inserted records to be rolled back.
So I decorated the repository method with @Transactional(propagation = Propagation.REQUIRED). But still I don't see the previous records being rolled back if the insert failed.
Then I understood that the rollback is not done because each insert is done in its own transaction and committed before the repository is returned.
So then I decorated the service method also with the same annotation @Transactional(propagation = Propagation.REQUIRED). But no success. The records are still not being rolled back.
Then, I understood that I have to insert all the records under the same transaction. So I changed my repository signature to
public void importInsuranceEstimates(List<String[]> insuranceEstimates)
then service class
repository.importInsuranceEstimates(insuranceEstimates);
In the repository class I am using batchUpdate instead of using the regular update.
What I understood is 1. queries related to a single transaction must be run/executed under a single transaction. 2. annotation based rollback is not possible using JdbcTemplate. We have to get the connection and play with setAutoCommit(boolean) method.
Are my observations right?
Also, in some cases one would like to make multiple insert/update/delete db calls for different tables from service layer. How to make multiple db calls from service layer under the same transaction. Is it even possible?
For example I want to write a code to transfer money from an account to another. So I have to make two db calls, one to debit the send and one to credit the receiver. In this case I would write something like below
Service class
repository.debitSender(id, amount);
repository.creditReceiver(id, amount);
Since I cannot run these two method calls under the same transaction, I have to modify my service class to
repository.transferMoney(senderId, receiverId, amount)
and do the two updates under the same transaction in the repository like below
public void transferMoney(String senderId, String receiverId, double amount) {
jdbcTemplate.getConnection().setAutoCommit(false);
// update query to debit the sender
// update query to credit the receiver
jdbcTemplate.getConnection().setAutoCommit(true);
}
What if I do not want to use transferMoney method and instead split the method into two - debitSender and creditReceiver and call these two methods from the service class under the same transaction with JdbcTemplate?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
