个人随笔
目录
四、oracle锁表修改经验:禁止循环单条锁以及连表锁
2021-01-20 15:40:18

为什么一条条锁会造成死锁?

有时候,我们需要修改某一个表的数据,但是那个表的数据是大家都可以修改的,比如下面的一个场景:

用户获得奖品1,2,3,4,5,6,然后每个奖品要去扣库存,如果不注意的话,可能会有如下操作

原因分析

  1. for(奖品ID序号)
  2. select * from 奖品表 where id=奖品id for update
  3. 扣库存

猛一看没毛病,每条记录都要修改库存,完全OK!
其实这段代码在多线程的情况下会高可能性造成死锁的,分析如下。

线程A进来了,开始一条条执行锁:

  1. 1
  2. 2
  3. 3

线程B进来了,开始一条条执行锁

  1. 6
  2. 5
  3. 4

然后线程A要锁4,5,6,因为被B先锁了只能等待,线程B要锁1,2,3也是一样因为被A先锁了要等待,所以就造成死锁了。

解决办法

可以执行如下语句一起锁

  1. select * from 奖品表 where id in(奖品序号) for update

这样子就不会造成死锁了,并且不会有多次的TCP交互,提高了应用的效率。

为什么不能链表锁

举个例子,有时候我们要进行行锁修改记录,但是要锁的表信息不够,此时你可能会做如下的操作:

  1. select t1.seq,t1.status,t2.info from 要锁的表 t1,要查数据的表 t2 where t1.seq='ss' and t1.a=t2.a for update

看起来是一下子就把想要的数据查回来了,可要查数据的表里的数据并不是属于自己的数据,别人也要用,但是也被锁住了,极大的降低了程序的效率。

 392

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号-2