I have the following implementation.
@Transactional
public void saveAndGenerateResult(Data data) {
saveDataInTableA(data.someAmountForA);
saveDataInTableB(data.someAmountForB);
callAnAggregatedFunction(data);
}
public void saveDataInTableA(DataA a) {
tableARepository.saveAndFlush(a);
}
public void saveDataInTableA(DataB b) {
tableBRepository.saveAndFlush(b);
}
public void callAnAggregatedFunction() {
// Do something based on the data saved from the beginning in Table A and Table B
}
It is important to use saveAndFlush
to have the data immediately available to the callAnAggregatedFunction
function to get an aggregated result and save it to another table. That is why I am not using save
function which does not flush the transactions into database immediately as far as I know.
However, I am using a @Transactional
annotation over the function saveAndGenerateResult
, as I want to rollback the database transactions that I have done in that function in case of any failure which is normally ensured by having a @Transactional
annotation over a method.
What will be the scenario in this specific case? I am using saveAndFlush
which flushes the data immediately into the database table and if the last function (i.e. callAnAggregatedFunction
) fails to write the data into the table, will the previous write operations in table A and table B will be rollbacked?
No. It doesn't flush data directly to a database until and unless we explicitly call flush and commit method. It's flush directly flush data to a database. It doesn't flush data directly to a database, therefore, changes will not be visible outside the transaction unless we explicitly call commit() in this transaction.
The @Transactional annotation makes use of the attributes rollbackFor or rollbackForClassName to rollback the transactions, and the attributes noRollbackFor or noRollbackForClassName to avoid rollback on listed exceptions. The default rollback behavior in the declarative approach will rollback on runtime exceptions.
The answer your question is no - @Transactional will have no effect if used to annotate private methods. The proxy generator will ignore them. When using proxies, you should apply the @Transactional annotation only to methods with public visibility.
You should use @Transactional at service layer, if you want to change the domain model for client B where you have to provide the same data in a different model,you can change the domain model without impacting the DAO layer by providing a different service or by creating a interface and implementing the interface in ...
Will the previous write operations in table A and table B be rollbacked?
Yes, unless your saveAndFlush()
methods have their own transactions (i.e. with propagation = REQUIRES_NEW
).
If they're all part of the transaction you started in saveAndGenerateResult()
, all modifications made to the database will be rolled back in case of failure.
For more information: Spring - @Transactional - What happens in background?
Spring @Transactional - isolation, propagation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With