Declarative Transaction Management with Spring

Spring’s transaction abstraction lets you demarcate units of work so that either every participating database statement succeeds or the entire sequence is rolled back. While JDBC already offers Connection#setAutoCommit(false), Spring adds portable configuration, propagation rules, and AOP-based declarations that can be applied at the service layer instead of polluting your data-access code.

Core API

public interface TransactionManager {
    void commit(TransactionStatus tx) throws TransactionException;
    void rollback(TransactionStatus tx) throws TransactionException;
}

The concrete implementation most often used with MyBatis or plain JDBC is DataSourceTransactionManager. It delegates to java.sql.Connection under the hood, so no extra libraries are required.

Enabling Annotation-Driven Transactions

  1. Annotate the service interface (preferred) or the concrete class with @Transactional. Placinng it on the enterface keeps your implementation decoupled from Spring APIs.

    public interface PaymentService {
        @Transactional
        void transfer(String from, String to, BigDecimal amount);
    }
    
  2. Expose a transaction manager bean. The following Java-config example wires the application’s DataSource into DataSourceTransactionManager.

    @Bean
    public PlatformTransactionManager txManager(DataSource ds) {
        return new DataSourceTransactionManager(ds);
    }
    
  3. Activate processing of @Transactional by adding @EnableTransactionManagement to any @Configuration class.

    @Configuration
    @ComponentScan("com.example")
    @Import({DataConfig.class, MyBatisConfig.class})
    @EnableTransactionManagement
    public class AppConfig { }
    

Transaction Participants

  • Transaction Manager – the method that starts the logical unit of work (usually a service method annotated with @Transactional).
  • Participant Resource – any repository or DAO method invoked inside that unit. By default it simply joins the existing transaction instead of creating a new one.

Propagation Rules

Propagation defines how a participant reacts when it is invoked inside an already running transaction. The most common settings are:

Propagation Behaviour
REQUIRED Join the current transaction; create a new one if none exists (default).
REQUIRES_NEW Suspend the current transaction and start a brand-new one.
public interface AuditService {
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    void logTransfer(String from, String to, BigDecimal amount);
}

Using REQUIRES_NEW above guarantees that the audit record is committed even if the surrounding business transaction rolls back.

Tags: Spring Framework Transaction Management Declarative Transactions DataSourceTransactionManager REQUIRES_NEW

Posted on Mon, 14 Sep 2026 16:25:50 +0000 by Orpheus13