@Transactional annotation in Hibernate

Author Avatar
Learn Here Fun Pedia
5 min read •

@Transactional

Now we need to connect everything. Spring's @Transactional annotation is primarily used to define a transaction boundary around a method or a class.

Example:

@Transactional
public void transferMoney() {
    debitAccount();
    creditAccount();
}

Conceptually, the successful flow looks like this:

Method starts
     ↓
Transaction begins
     ↓
operations
     ↓
flush
     ↓
commit

If an appropriate exception is thrown during the execution, it causes a rollback:

Method starts
     ↓
Transaction begins
     ↓
operation 1
     ↓
operation 2
     ↓
exception
     ↓
ROLLBACK

19. Why @Transactional Is Important with Hibernate

Hibernate works with a persistence context and a database transaction. The two must coordinate seamlessly.

Suppose you have the following code:

@Transactional
public void updateEmployee() {
    Employee e = entityManager.find(Employee.class, 101L);
    e.setSalary(60000);
}

Here is the typical Spring Boot + JPA flow you should visualize when this method is called:

@Transactional
       ↓
Spring transaction begins
       ↓
Persistence Context opens
       ↓
find() 
       ↓
Employee becomes managed
       ↓
setSalary() 
       ↓
Dirty Checking
       ↓
flush (SQL UPDATE generated)
       ↓
commit (Data saved permanently)

20. Important: @Transactional Does Not Mean "Flush"

Don't say: "@Transactional immediately executes SQL." It doesn't.

@Transactional establishes the transaction semantics. It wraps the method in a database transaction boundary. Hibernate determines when pending changes are actually flushed to the database based on its flush mode (usually AUTO) and when the transaction completes.

The typical lifecycle is:

@Transactional method called
      ↓
Transaction Begins
      ↓
Persistence Context
      ↓
Dirty Checking (in memory)
      ↓
Flush (Hibernate decides when to send SQL)
      ↓
SQL Executed against DB
      ↓
Commit (Method ends successfully)

Interactive Look: The @Transactional Lifecycle

Step through this interactive sequence to see exactly how Spring's transaction boundary wraps Hibernate's internal persistence context lifecycle.

diagram Idea: An interactive step-by-step sequence diagram illustrating the lifecycle of a Spring @Transactional method, showing the handoff between Spring and Hibernate. Visual type: Sequence/State Diagram Data specification: - Data structure: Sequential steps mapping a method call to its underlying database and ORM actions. - Initial values: Steps: 1. Method Intercepted (Spring AOP opens Transaction) 2. Persistence Context Opened (Hibernate Session active) 3. Entity Loaded (State: Managed) 4. Entity Modified (State: Dirty) 5. Method Returns (Success) 6. Flush Triggered (Dirty Checking -> SQL UPDATE sent) 7. Commit (Transaction finalized in DB) - Mapping: Nodes representing the states, with a timeline view. User controls: "Next Step" and "Previous Step" buttons. Interactivity: Stepping through highlights the active layer (Spring AOP, Hibernate ORM, Database). Animation: Smooth transitions showing data moving from memory (Dirty) to Database buffer (Flush) to finalized storage (Commit).

T3 Interview Summary

If the interviewer asks: "Does @Transactional force Hibernate to execute SQL immediately?"

"No, it does not. @Transactional simply defines the logical boundaries (begin and commit/rollback) of a database transaction. Hibernate manages the actual SQL execution through its Persistence Context. Operations are held in memory, and Hibernate performs dirty checking and delays the SQL execution (flush()) until it is absolutely necessary, or right before the Spring transaction commits."

Important Interview Questions (FAQs)

Q1: What happens if an exception is thrown inside a @Transactional method?

By default, Spring will catch the runtime (unchecked) exception and issue a rollback command to the database. Any SQL that was flushed during the method execution will be discarded by the database, maintaining atomicity.

Q2: Can I manually call flush() inside a @Transactional method?

Yes, you can call entityManager.flush() manually. This will force Hibernate to send pending SQL statements (like updates from dirty checking) to the database immediately, but the changes will still not be permanent until the method finishes and the transaction commits.

Q3: Why is Dirty Checking so powerful with @Transactional?

It removes the need to write boilerplate update() methods. You simply load an entity, modify it using normal Java setters, and let the @Transactional boundary end. Hibernate automatically detects the changes and handles the SQL UPDATE for you.

Comments (0)