记录一个关于事务的问题

场景:
在分布式多台服务的情况下,有两个请求同时调用AB接口,AB接口有一个共同的D方法,AB方法加了事务且加了锁,D方法也加了事务和锁,D方法的使用场景是用来控制一个活动的参与次数(即数据库的条数),假如次数为200,D方法会先查询数据库条数是否大于等于200,如果条件成立则拦截掉,不成立则进行insert操作

产生的问题:
AB接口共同请求D方法的时候,假如A先请求到D方法,上锁-处理逻辑-释放锁,A方法的事务还未提交,B方法马上调用到D 同样的操作上锁-处理逻辑-释放锁,由于A方法的事务还没提交,导致B方法的查询条数不一致的情况

产生问题的原因:
事务未提交导致,查询的数据是未提交之前的

临时解决问题的办法:
最开始是想到个临时解决方案,就是用redis记录条数,这样就不用理会事务是否提交;

最终解决问题的办法:
使用编程式事务控制D方法,释放锁之前将事务commit, 注意编程式事务不要搭配@Transactional注解一起使用,否则会无效;

编程式事务的使用方法:
1、

声明

    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    private TransactionDefinition transactionDefinition;

2、方法中引用,获取事务的状态

TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);

3、提交事务

dataSourceTransactionManager.commit(transactionStatus);

4、防止出现异常,所以在try中加上回滚代码

dataSourceTransactionManager.rollback(transactionStatus);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值