一次使用spring事务以及悲观锁的经历

一、悲观锁和乐观锁

1.悲观锁:顾名思义,认为数据被并发修改的几率非常大,每次修改数据前,都先对数据进行上锁处理,即用select****for update进行上锁,而平常使用的synchronized其实也是悲观锁的一种应用。
2.乐观锁:顾名思义,每次修改前,都认为数据不会造成冲突,只有在修改时,才去检测数据是否冲突;

二、 for update的使用

1.示例:select * from table where xxx for update
2. 锁级别:for update仅适用于innoDB,而InnoDB默认是行级别的锁,当有明确指定的主键时候,是行级锁。否则是表级锁;
3. 注意点:需与事务搭配使用,否则锁不生效;

三、下单修改库存时的踩坑事件:

事件1:项目经过多人接手,代码非常乱,整个下单接口中直接使用了@Transactional,而因为本项目中会调很多个系统的接口,这就直接会导致一次事务要经过十秒甚至更多时间才结束,这种场景直接用悲观锁时,会导致两个用户下同样的单时,第一个用户正常调用接口正常下单, 而第二个用户却会因为悲观锁把该商品数据锁住而需要等到第一个用户下单结束后才会继续下单流程:
解决方式:单独将修改库存这块放到同一个方法中,并使用@Transactional(propagation = Propagation.REQUIRES_NEW)新开一个事务,进行事务嵌套;

事件2:当我使用@Transactional(propagation = Propagation.REQUIRES_NEW)多次测试时,发现实际上并没有开启新事务:
解决方式:当外层事务与内层事务在同一个类中时,spring并不会创建一个新的事务,需要把两个事务放在不同的类中;

事件3:当我在内层事务中新增一条数据后,在外层事务中查询不到新增的数据;
解决方式:用@Transactional(propagation = Propagation.REQUIRES_NEW)新开一个内层事务去查询,则能够查询出另一个内层事务新增或修改的数据,即外层事务嵌套了两个内层事务,上面提到了外层事务不能与内层事务放在同一个类中,而内层事务跟内层事务则允许放在同一个类中;

四、剩余疑问点:

1.事件三中,内层事务已提交(证明点:悲观锁会随着事务的提交而解锁),但是在外层事务却查不到内层事务更改的数据,而嵌套的内层事务却能正常查询到另一个内层事务更改的数据;
2.如果悲观锁只查询但不进行其他操作,事务提交后,会不会释放锁:答案是会。
ps:第一点以后知道原因再进行补充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值