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

 


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

 


1️⃣ Hierarchy of Transaction Managers (Page-1 Diagram)

Core Interfaces & Classes

  1. TransactionManager
    • Top-level marker interface.
  2. PlatformTransactionManager (extends TransactionManager)
    • Defines 3 core methods:
      • getTransaction()
      • commit()
      • rollback()
  3. AbstractPlatformTransactionManager (abstract class)
    • Provides default implementation for:
      • Transaction lifecycle
      • Commit & rollback handling
    • Concrete managers extend this.

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:

  1. Create TransactionDefinition
  2. Start transaction
  3. 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:
    • RuntimeException
    • Error
  • ❌ 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


 

Leave a Reply