Does Spring @Transactional annotated on method ensure the flush of data exactly when the method ends?

Viewed 1399

I have this simplified escenario in a Spring application with Java and Hibernate for persistence provider:

@Transactional
void method1() { // some savings}

@Transactional
void method2() { // some savings}

When I run a parent method (not annotated as transactional)

void parentMethod() {
    method1();
    method2();
}

Can I make sure that when the method finishes the changes are impacted in the database immediately before the method is called? Or that changes could be flush to database later, with some delay?

I'm interested on other applications seeing the changes made in database immediately when method1 finishes (and before method2 be called)

Update My parent method is not defined in the same class, and the class and firm of the my parent method has not @Transactional annotation

Thanks!

1 Answers

To your question ... ensure the flush of data exactly when the method ends? No, not exactly when the method ends, but latest when the method ends.

Within transaction you can flush the current state as many times as you wish. Flushing means that you synchronize your JPA session with database. See Hibernate doc regarding this. Flushing does not mean your changes are durable; if transaction rolls back later on, these changes will be automatically reverted. The commit operation performs different steps, one of them is to ensure that the JPA (e.g. Hibernate) session is synchronized with DB, and, if needed, calls flush. If the session is already synchronized, flush will be skipped.

In the comments you wrote that the class and the method parentMethod are not transactional and that method1() and method2() are defined in a separate class. In such case when the method1() is called, a new transaction will be started. When this method ends, this transaction will be committed. Any changes in the database done by this method will be durable, i.e. no matter what happens later on (exceptions, roll backs in other methods) these changes will remain in the database.

Some information relevant to your case can be found here because following is important:

  1. If these methods are in the same class or not and
  2. If you use Spring own AOP or AspectJ. Besides it depends on the class where your parentMethod is defined. If it is transactional, then these 2 calls will run within the existing transaction and there will be no commit after the 1st one is committed.
Related