spring事务上的坑(90%的程序员不知道)

    xiaoxiao2025-08-03  20

    spring事务上的坑

    1.前言

    近期有位同事看了我的定时器代码,提醒我一个隐藏bug——spring事务

    在方法内调用事务,事务无法生效!于是我开始测试与整理spring事务中可能遇到的坑

    2.问题复现

    如下代码,在类内部调用事务是不会生效的,因为没有走类代理!事务是切在类上,只有通过调用 类.方法才会走spring的事务管理!

    @Component public class TimerTest { private static final Logger logger = LoggerFactory.getLogger(TimerTest.class); @Autowired private SysDaoAgent agent; @Autowired private ServiceTest serviceTest; @Scheduled(fixedRate = 10 * 60 * 1000, initialDelay = 5 * 1000) public void start() { test();//不走代理 // serviceTest.test();//切面切在类上 ((TimerTest)AopContext.currentProxy()).test();//获取当前代理再去调用才行 } @Transactional public void test(){ agent.quickSimpleDao.update("update qhb_star_user set is_del = 5 where seq_id=8299"); if(true){ throw new RuntimeException("err"); } agent.quickSimpleDao.update("update qhb_star_user set is_del = 2 where seq_id=8298"); } }

    3.其他常见的事务坑

    1、首先要看数据库本身对应的库、表所设置的引擎是什么。MyIsam不支持事务,如果需要,则必须改为InnnoDB。

    2、@Transactional所注解的方法是否为public

    3、@Transactional所注解的方法所在的类,是否已经被注解@Service或@Component等。

    4、需要调用该方法,且需要支持事务特性的调用方是在在 @Transactional所在的类的外面。注意:类内部的其他方法调用这个注解了@Transactional的方法,事务是不会起作用的。

    5、注解为事务范围的方法中,事务的回滚仅仅对于unchecked的异常有效。对于checked异常无效。也就是说事务回滚仅仅发生在出现RuntimeException或Error的时候。

    如果希望一般的异常也能触发事务回滚,需要在注解了@Transactional的方法上,将@Transactional回滚参数设为:

    @Transactional(rollbackFor=Exception.class)

    6、非springboot项目,需要检查spring配置文件xml中:

    (1)扫描包范围是否配置好,否则不会在启动时spring容器中创建和加载对应的bean对象。

    <context:component-scan base-package="com.happybks" ></context:component-scan>(2)事务是否已经配置成开启

    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

    4.总结

    对于事务一定要重视,重视,再重视!为什么?作为程序员,这还需要解释么?

    更多事务原理请具体查看  链接

    最新回复(0)