@Transactional导致的生产事故

本文探讨了@Transactional注解在高并发场景下可能导致的数据库连接池耗尽、死锁等问题,详细阐述了长事务的概念及其引发的危害,如连接资源耗尽、数据库回滚时间长等。建议通过拆分事务方法、使用编程式事务等方式避免长事务,提高事务处理效率和系统的稳定性。

@Transactional导致的生产事故

当我们遇到一个长事务的时候,尽量不要是用@Transactional注解

因为当高并发的时候可能出现:数据库监控平台一直收到告警短信,数据库连接不足,出现大量死锁;日志显示调用流程引擎接口出现大量超时;同时一直提示CannotGetJdbcConnectionException,数据库连接池连接占满。

原因:当 Spring 遇到该注解时,会自动从数据库连接池中获取 connection,并开启事务然后绑定到 ThreadLocal 上,对于@Transactional注解包裹的整个方法都是使用同一个connection连接。如果我们出现了耗时的操作,比如第三方接口调用,业务逻辑复杂,大批量数据处理等就会导致我们我们占用这个connection的时间会很长,数据库连接一直被占用不释放。一旦类似操作过多,就会导致数据库连接池耗尽。

何为长事务?

顾名思义就是运行时间比较长,长时间未提交的事务,也可以称之为大事务。

长事务会引发哪些问题?

长事务引发的常见危害有:

(1)数据库连接池被占满,应用无法获取连接资源;
(2)容易引发数据库死锁;
(3)数据库回滚时间长;
(4)在主从架构中会导致主从延时变大。

如何避免长事务?
既然知道了长事务的危害,那如何在开发中避免出现长事务问题呢?
很明显,解决长事务的宗旨就是 对事务方法进行拆分,尽量让事务变小,变快,减小事务的颗粒度。
既然提到了事务的颗粒度,我们就先回顾一下Spring进行事务管理的方式。

基于底层的API,开发者在代码中手动的管理事务的开启、提交、回滚等操作。在spring项目中可以使用TransactionTemplate类的对象,手动控制事务。

@Autowired 
private TransactionTemplate transactionTemplate; 
 
... 

public void save(RequestBill requestBill) {
   
    
    transactionTemplate.execute(transactionStatus -> {
   
   
        requestBillDao.save(requestBill);
        //保存明细表
        requestDetailDao
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱上编程2705

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值