spring编程式事务和声明式事务都怎么用,里面包含的参数都有什么,原理?

在 Spring 框架中,事务管理分为编程式事务和声明式事务两种方式。下面详细说明两者的用法、核心参数和示例:


一、编程式事务 (Programmatic Transaction)

通过代码手动控制事务的开启、提交和回滚。
核心类:TransactionTemplate 或 PlatformTransactionManager

1. 使用 TransactionTemplate(推荐)

@Service
public class UserService {
    private final TransactionTemplate transactionTemplate;

    // 通过构造器注入
    public UserService(PlatformTransactionManager transactionManager) {
        this.transactionTemplate = new TransactionTemplate(transactionManager);
        
        // 设置事务参数(可选)
        transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        transactionTemplate.setTimeout(30); // 单位:秒
    }

    public void updateUser(User user) {
        transactionTemplate.execute(status -> {
            try {
                // 1. 执行业务操作(如 DAO 调用)
                userDao.update(user);
                // 2. 可继续执行其他数据库操作
                // ...
                return null; // 返回结果(如有)
            } catch (Exception e) {
                status.setRollbackOnly(); // 标记回滚
                throw e;
            }
        });
    }
}

  

2. 使用 PlatformTransactionManager(更底层)

@Autowired
private PlatformTransactionManager transactionManager;

public void updateUser(User user) {
    // 定义事务属性
    DefaultTransactionDefinition def = new DefaultTransactionDefinition();
    def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
    def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    def.setTimeout(30);

    TransactionStatus status = transactionManager.getTransaction(def);
    try {
        // 业务操作
        userDao.update(user);
        transactionManager.commit(status); // 提交事务
    } catch (Exception e) {
        transactionManager.rollback(status); // 回滚事务
        throw e;
    }
}

  

核心参数(TransactionDefinition):

参数说明
isolation 隔离级别(默认:ISOLATION_DEFAULT
propagation 传播行为(默认:PROPAGATION_REQUIRED
timeout 超时时间(秒,默认:-1,使用底层事务系统默认值)
readOnly 是否只读事务(默认:false)
rollbackFor 触发回滚的异常类型(编程式中需手动调用 setRollbackOnly()

二、声明式事务 (Declarative Transaction)

通过注解或 XML 配置声明事务规则,由 Spring AOP 在运行时自动管理事务。
推荐方式:使用 @Transactional 注解。

1. 启用声明式事务

在配置类添加注解:

@Configuration
@EnableTransactionManagement // 启用事务管理
public class AppConfig {
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource); // JDBC 事务管理器
    }
}

2. 使用 @Transactional 注解

@Service
public class UserService {
    @Autowired
    private UserDao userDao;

    // 在方法或类上添加注解
    @Transactional(
        isolation = Isolation.READ_COMMITTED,
        propagation = Propagation.REQUIRED,
        timeout = 30,
        readOnly = false,
        rollbackFor = {SQLException.class, BusinessException.class} // 指定回滚异常
        // noRollbackFor = 指定不回滚的异常
    )
    public void updateUser(User user) {
        userDao.update(user);
        // 其他数据库操作...
        // 若抛出 RuntimeException 或 Error 自动回滚
        // 受检异常需通过 rollbackFor 显式配置
    }
}

@Transactional 核心参数:

参数说明
isolation 隔离级别(默认:Isolation.DEFAULT
propagation 传播行为(默认:Propagation.REQUIRED
timeout 超时时间(秒,默认:-1)
readOnly 是否只读事务(默认:false)
rollbackFor 触发回滚的异常类型(默认:RuntimeException 和 Error
noRollbackFor 不触发回滚的异常类型
label 事务标签(Spring 5.3+)

三、事务传播行为(Propagation Behavior)

传播行为类型说明
REQUIRED(默认) 当前有事务则加入,无事务则新建
REQUIRES_NEW 始终新建事务,挂起当前事务(独立提交)
SUPPORTS 有事务则加入,无事务则以非事务方式执行
NOT_SUPPORTED 以非事务方式执行,挂起当前事务
MANDATORY 必须在事务中调用,否则抛异常
NEVER 必须在非事务中执行,否则抛异常
NESTED 嵌套事务(基于保存点实现,外层回滚内层也会回滚)

四、隔离级别(Isolation Level)

隔离级别说明
DEFAULT 使用数据库默认隔离级别
READ_UNCOMMITTED 可能读到未提交数据(脏读)
READ_COMMITTED(最常用) 避免脏读,可能不可重复读
REPEATABLE_READ 避免脏读、不可重复读
SERIALIZABLE 最高隔离级别(性能最低)

五、Spring Boot 中的事务自动装配

Spring Boot 通过 @EnableTransactionManagement 自动启用事务支持,并根据依赖自动配置事务管理器:

如果存在单数据源 → 注册 DataSourceTransactionManager
如果存在 JTA → 注册 JtaTransactionManager
配置示例(application.properties):

spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=123456
spring.jpa.hibernate.ddl-auto=update

六、事务与 AOP 的关系

组件 作用
TransactionInterceptor 事务切面,拦截方法并控制事务
TransactionAttributeSource 解析 @Transactional 注解,获取事务属性
TransactionAspectSupport 提供事务处理的基础支持
ProxyFactory 创建动态代理(JDK/CGLIB)

PlatformTransactionManager核心接口    

 

选择建议

  • 声明式事务:适用于大多数业务场景(简洁、解耦)。

  • 编程式事务:需要精细控制事务边界时使用(如分段提交)。

注意:

  1. @Transactional 注解应作用于 public 方法上(AOP 代理限制)。

  2. 避免在同一个类中调用 @Transactional 方法(自调用失效问题)。

  3. 默认只对 RuntimeException 回滚,受检异常需显式配置 rollbackFor

posted @ 2025-06-26 01:15  飘来荡去evo  阅读(81)  评论(0)    收藏  举报