What is @Transactional Annotation in Spring Boot?
@Transactional is a Spring annotation used to manage database transactions automatically.
It ensures that:
- All database operations inside a method succeed together
- Or all operations fail together
In simple words:
“@Transactional makes database operations safe, consistent, and reliable.”
Why @Transactional is Needed
Enterprise applications often execute multiple database operations together.
Examples:
- Bank money transfer
- Payment processing
- Order placement
- Ticket booking
If one operation fails in the middle:
- Database may become inconsistent
- Partial data may be saved
@Transactional prevents such problems.
Real-Time Banking Example
Suppose:
- ₹10,000 transferred from Account A to Account B
Steps:
- Deduct money from Account A
- Add money to Account B
Problem:
- If step 1 succeeds
- But step 2 fails
Money disappears from the system.
@Transactional solves this issue using rollback.
Basic @Transactional Example
@Transactional
public void transferMoney() {
}
How @Transactional Works Internally
Spring automatically:
- Starts a transaction
- Executes method logic
- Commits transaction if successful
- Rolls back if exception occurs
Transaction Flow
Start Transaction
↓
Execute Operations
↓
Success?
↓ ↓
Yes No
↓ ↓
Commit Rollback
Money Transfer Example
@Service
public class BankService {
@Transactional
public void transferMoney(
Long fromAccount,
Long toAccount,
Double amount
) {
withdraw(fromAccount, amount);
deposit(toAccount, amount);
}
}
Generated SQL Example
UPDATE accounts
SET balance = balance - 10000
WHERE id = 1;
UPDATE accounts
SET balance = balance + 10000
WHERE id = 2;
Successful Transaction Example
If both queries execute successfully:
- Transaction commits
Failed Transaction Example
If second query fails:
- Entire transaction rolls back
What is Commit?
Commit means:
- Permanently save changes into database
What is Rollback?
Rollback means:
- Undo all changes made during transaction
Default Rollback Behavior
By default:
- Rollback occurs only for RuntimeException
RuntimeException Example
@Transactional
public void processPayment() {
throw new RuntimeException();
}
Transaction rolls back automatically.
Checked Exception Example
Checked exceptions do NOT rollback automatically.
Example
@Transactional(
rollbackFor = Exception.class
)
public void processPayment()
throws Exception {
throw new Exception();
}
What is rollbackFor?
rollbackFor specifies
which exceptions should trigger rollback.
Example
@Transactional(
rollbackFor = IOException.class
)
Read-Only Transactions
Read-only transactions improve performance for fetch operations.
Example
@Transactional(readOnly = true)
public List<Student> getStudents() {
return repository.findAll();
}
Why readOnly Improves Performance
Hibernate skips:
- Dirty checking
- Unnecessary updates
Transaction Propagation
Propagation defines:
- How transactions behave when methods call each other
Main Propagation Types
| Propagation | Description |
|---|---|
| REQUIRED | Use existing transaction or create new |
| REQUIRES_NEW | Always create new transaction |
| SUPPORTS | Use existing transaction if available |
| NOT_SUPPORTED | Run without transaction |
Propagation Example
@Transactional(
propagation =
Propagation.REQUIRES_NEW
)
Transaction Isolation Levels
Isolation controls:
- How transactions interact with each other
Main Isolation Levels
| Isolation Level | Description |
|---|---|
| READ_UNCOMMITTED | Can read uncommitted data |
| READ_COMMITTED | Reads only committed data |
| REPEATABLE_READ | Repeated reads return same data |
| SERIALIZABLE | Highest isolation level |
Isolation Example
@Transactional(
isolation =
Isolation.READ_COMMITTED
)
Where @Transactional Can Be Used
- Service methods
- Class level
- Repository methods
Class-Level Example
@Service
@Transactional
public class StudentService {
}
Method-Level Example
@Transactional
public void saveStudent() {
}
Why Service Layer is Preferred
Best practice:
- Use @Transactional in service layer
because:
- Business logic exists there
- Multiple repositories may be involved
What is Dirty Checking?
Hibernate automatically detects entity changes and updates database records.
Dirty Checking Example
@Transactional
public void updateStudent(Long id) {
Student student =
repository.findById(id).get();
student.setName("Naresh");
}
Hibernate automatically updates database.
Advantages of @Transactional
- Maintains data consistency
- Automatic rollback support
- Reduces manual transaction code
- Improves reliability
- Simplifies database operations
Disadvantages of Improper Transaction Usage
- Deadlocks
- Long-running transactions
- Database locking issues
- Performance problems
Real-Time Example in E-Commerce Application
Order placement may involve:
- Saving order
- Updating inventory
- Processing payment
If payment fails:
- Entire transaction should rollback
Best Practices for @Transactional
- Keep transactions short
- Use readOnly for fetch operations
- Avoid transactions in controllers
- Handle exceptions properly
- Use proper isolation levels
Common Interview Questions on @Transactional
What is @Transactional annotation?
It manages database transactions automatically in Spring Boot.
What happens if exception occurs inside @Transactional method?
Transaction rolls back automatically.
What is rollbackFor?
It specifies exceptions that should trigger rollback.
What is readOnly transaction?
A transaction optimized for read operations.
Why is @Transactional used in service layer?
Because business logic usually exists there.
Conclusion
@Transactional is one of the most important annotations
in Spring Boot enterprise application development.
It helps developers:
- Maintain database consistency
- Prevent partial updates
- Handle failures safely
- Build reliable applications
Understanding @Transactional is essential
for Spring Boot developers because enterprise systems
heavily depend on reliable and consistent database operations.
Proper use of transactions improves:
- Data integrity
- Application stability
- Performance
- Scalability