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

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.总结

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值