【SpringBoot优雅处理长事务】


前言

在我们日常开发的过程中,如果无脑的使用长事务(运行时间长,长时间未提交的事务,都可以称之为长事务),引发如下的一些危害:

  1. 数据库连接池被占满,应用无法获取连接资源
  2. 容易引发数据库死锁
  3. 数据库回滚时间长

综上,合理的对事务进行拆分,尽量让事务变小,变快,减小事务的颗粒度显得尤为重要;如下,提供三种常见的解决方案;


1、编程式事务

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

@Autowired 
private TransactionTemplate transactionTemplate; 
 
... 

public void save(ArtisanDto artisanDto) { 
    transactionTemplate.execute(transactionStatus -> {
        artisanDao.save(artisanDto);
        //....
        // .....
        return Boolean.TRUE; 
    });
}

使用编程式事务最大的好处就是可以精细化控制事务范围, 所以避免长事务最简单的方法就是不要使用声明式事务@Transactional,而是使用编程式事务手动控制事务范围。

2、手动管理事务

有些情况下,可能需要手动控制事务的开始、提交和回滚等操作。可以通过注入 PlatformTransactionManager 依赖来手动管理事务。

@Autowired
private PlatformTransactionManager transactionManager;

public void longTransactionMethod() {
    TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());

    try {
        // 长事务的处理逻辑

        transactionManager.commit(status);
    } catch (Exception e) {
        transactionManager.rollback(status);
        throw e;
    }
}

3、方法拆分

使用@Transactional 又想避免产生长事务,建议对我们的方法进行拆分,将不需要事务管理的逻辑与事务操作分开。

@Service
public class ArtisanService{

    public void create(ArtisanDto dto){
        queryData();
        biz();
        save(dto);
    }
  
	//事务操作
    @Transactional(rollbackFor = Throwable.class)
    public void save(ArtisanDto  dto){
        artisanDao.insert(dto);
    }
}

queryData()与biz()不需要事务,我们将其与事务方法save()拆开.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值