Spring声明式事务生效是有条件滴!

在日常工作中,经常使用@Transactional 注解进行事务的声明,但如果发现事务未生效,可以从下面几个方面进行排查。


常见失效场景总结

场景原因解决方案
内部方法调用绕过了Spring代理注入自身或使用AopContext
private方法AOP无法增强改为public方法
final方法/类无法被代理移除final修饰符
非Spring管理不是代理对象确保Bean由Spring管理
异常被捕获异常未抛出到代理层检查异常处理逻辑
数据库不支持如MyISAM引擎使用InnoDB等支持事务的引擎

1、配置事务管理器

在服务的启动类,需要配置@EnableTransactionManagement,核心作用是启用Spring的声明式事务管理功能

在Spring Boot中,通常不需要显式添加@EnableTransactionManagement;但如果exclude = {DataSourceAutoConfiguration.class}排除了DataSource自动配置,则需要显式声明

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) // 排除是由于项目需要,需要声明多数据源
@EnableTransactionManagement  // 激活事务管理
public class Application {
    // 启用后,Spring会为带有@Transactional的Bean创建代理
}

或者可以使用XML配置方式配置

<tx:annotation-driven transaction-manager="transactionManager"/>

2、代理机制生效

// ❌ 错误:内部方法调用,事务不生效
@Service
public class UserService {
    
    @Transactional
    public void methodA() {
        // 直接调用内部方法,事务失效
        this.methodB();
    }
    
    @Transactional
    public void methodB() {
        // 事务不会生效
    }
}

// ✅ 正确:通过Spring代理调用
@Service
public class UserService {
    @Autowired
    private UserService self; // 注入自己或通过ApplicationContext获取
    
    @Transactional
    public void methodA() {
        // 通过代理调用,事务生效
        self.methodB();
    }
    
    @Transactional
    public void methodB() {
        // 事务生效
    }
}

3、异常类型匹配

@Transactional(rollbackFor = Exception.class)
public String createTask(ModelTaskDTO modelTaskDTO) throws TException, InterruptedException {
    // 所有异常都会回滚
}

// 默认情况只回滚RuntimeException和Error
@Transactional // 只回滚RuntimeException
public void defaultRollback() {
    throw new IOException(); // 不会回滚
}

4、方法修饰符要求

public class ModelTrainingServiceImpl {
    
    // ✅ 正确:public方法
    @Transactional
    public String createTask() {
        // 事务生效
    }
    
    // ❌ 错误:private方法事务不生效
    @Transactional
    private void privateMethod() {
        // 事务不生效
    }
    
    // ❌ 错误:final方法无法被代理
    @Transactional
    public final void finalMethod() {
        // 事务不生效
    }
}

5、Bean必须由Spring管理

// ✅ 正确:Spring管理的Bean
@Service
public class ModelTrainingServiceImpl {
    @Transactional
    public void method() {
        // 事务生效
    }
}

// ❌ 错误:手动new的对象
ModelTrainingServiceImpl service = new ModelTrainingServiceImpl();
service.method(); // 事务不生效

6、数据库支持事务

  • 使用支持事务的数据库引擎(如MySQL的InnoDB)

  • 正确配置数据源和连接

7、事务传播行为

@Service
public class YourService {
    
    @Transactional(propagation = Propagation.REQUIRED)
    public void method1() {
        // 默认传播行为
    }
    
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void method2() {
        // 总是开启新事务
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值