📘 Spring Boot Transaction Management – @Transactional (Part-2)

1️⃣ Hierarchy of Transaction Managers (Page-1 Diagram)
Core Interfaces & Classes
- TransactionManager
- Top-level marker interface.
- PlatformTransactionManager (extends TransactionManager)
- Defines 3 core methods:
getTransaction()commit()rollback()
- Defines 3 core methods:
- AbstractPlatformTransactionManager (abstract class)
- Provides default implementation for:
- Transaction lifecycle
- Commit & rollback handling
- Concrete managers extend this.
- Provides default implementation for:
Concrete Implementations
| Transaction Manager | Used With | Type |
|---|---|---|
| DataSourceTransactionManager | JDBC | Local |
| JdbcTransactionManager | JDBC | Local |
| HibernateTransactionManager | Hibernate | Local |
| JpaTransactionManager | JPA | Local |
| JtaTransactionManager | JTA | Distributed |
✅ Important Note:
- JDBC, JPA, Hibernate → Local Transactions
- JTA → Distributed Transactions (multiple DBs / MQs)
2️⃣ Transaction Management Types
🔹 Declarative Transaction Management
- Done using @Transactional
- Managed by Spring automatically
- Clean & recommended
🔹 Programmatic Transaction Management
- Manual control using code
- More flexible but complex
3️⃣ Declarative Transaction Management (@Transactional)
Basic Example (from PDF)
@Component
public class User {
@Transactional
public void updateUser() {
System.out.println("Update query to update user DB values");
}
}
How Spring Chooses Transaction Manager
- Based on DataSource / JPA / Hibernate
- Spring Boot auto-configures the correct one
4️⃣ Explicit Transaction Manager Configuration (Page-2)
@Bean
public DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("org.h2.Driver");
ds.setUrl("jdbc:h2:mem:testdb");
ds.setUsername("sa");
ds.setPassword("");
return ds;
}
@Bean
public PlatformTransactionManager userTransactionManager(
DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
5️⃣ Using Named Transaction Manager
@Component
public class UserDeclarative {
@Transactional(transactionManager = "userTransactionManager")
public void updateUserProgrammatic() {
System.out.println("Insert Query ran");
System.out.println("Update Query ran");
}
}
📌 Use case:
When multiple DataSources exist in the application.
6️⃣ Programmatic Transaction Management
Two Approaches
✅ Approach-1: PlatformTransactionManager
Steps:
- Create
TransactionDefinition - Start transaction
- Commit / Rollback manually
✅ Approach-2: TransactionTemplate (Recommended)
- Cleaner than approach-1
- Handles commit & rollback internally
transactionTemplate.execute(status -> {
// DB operations
return null;
});
7️⃣ Transaction Propagation (Page-3 & 4)
Propagation defines how a method behaves when a transaction already exists.
🔹 REQUIRED (Default)
@Transactional(propagation = Propagation.REQUIRED)
- If parent txn exists → use it
- Else → create new txn
✅ Most commonly used
🔹 REQUIRES_NEW
@Transactional(propagation = Propagation.REQUIRES_NEW)
- Suspends parent transaction
- Creates a new transaction
- Parent resumes after completion
📌 Used for audit logs, notifications
🔹 SUPPORTS
@Transactional(propagation = Propagation.SUPPORTS)
- If txn exists → use it
- Else → run without transaction
🔹 NOT_SUPPORTED
@Transactional(propagation = Propagation.NOT_SUPPORTED)
- Suspends parent transaction
- Always runs without transaction
🔹 MANDATORY
@Transactional(propagation = Propagation.MANDATORY)
- If txn exists → use it
- Else → ❌ Exception
🔹 NEVER
@Transactional(propagation = Propagation.NEVER)
- If txn exists → ❌ Exception
- Else → run normally
8️⃣ Transaction Synchronization Check (Page-5 Output)
TransactionSynchronizationManager.isActualTransactionActive();
TransactionSynchronizationManager.getCurrentTransactionName();
Used to verify:
- Is transaction active?
- Current transaction name
🔥 EXTRA NOTES (Very Important – Not in PDF)
✅ Rollback Rules
- By default, Spring rolls back on:
RuntimeExceptionError
- ❌ Does NOT rollback on
Checked Exception
👉 Fix:
@Transactional(rollbackFor = Exception.class)
✅ Self-Invocation Problem
this.innerMethod(); // @Transactional ignored
✔ Solution:
- Call from another bean
- Or use
ApplicationContext.getBean()
✅ Proxy Limitation
- @Transactional works only on public methods
- Uses AOP proxy
🎯 Interview Questions & Answers
Q1. What is PlatformTransactionManager?
Ans:
It is the central interface in Spring that manages transactions using getTransaction(), commit(), and rollback().
Q2. Difference between REQUIRED and REQUIRES_NEW?
Ans:
- REQUIRED → joins existing transaction
- REQUIRES_NEW → suspends existing and creates new one
Q3. Which transaction manager is used for JPA?
Ans:
JpaTransactionManager
Q4. Why JTA is used?
Ans:
For distributed transactions involving multiple databases or message queues.
Q5. Does @Transactional work on private methods?
Ans:
❌ No. Only public methods due to proxy mechanism.
Q6. What happens if a checked exception occurs?
Ans:
Transaction will not rollback unless explicitly configured.
Q7. Which is better: Declarative or Programmatic?
Ans:
Declarative (@Transactional) – cleaner & recommended
Programmatic – used only when fine-grained control is needed