Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Transactional annotation works with saveAndFlush?

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?

like image 657
Reaz Murshed Avatar asked Apr 16 '18 10:04

Reaz Murshed


People also ask

Does saveAndFlush commit transaction?

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.

On which can be @transactional annotation be applied?

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.

Does @transactional works on private method?

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.

Can we use @transactional in DAO layer?

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 ...


1 Answers

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

like image 197
Kayaman Avatar answered Sep 26 '22 00:09

Kayaman