为什么要锁商品,而不锁库存。一文搞懂for update的使用,以及以最小程度的影响力进行加锁位置的定位方法

for update 只在事务中生效,(且加的是写锁,加锁期间可以读取这个记录,但是无法更改,发生更改行为时会进入等待锁释放的状态)

sql1没有锁
sql2有锁for update

在可重复读的隔离级别下:

  1. 有事务的情况下:
    两个事务同时开启,且A事务读了sql1语句,此时事务B也可以读取sql1,当事务A或B其中一个执行了sql2的时候,就会锁主sql2的表记录,此时另一个事务是无法执行sql2,只有等待刚才执行了sql2的事务结束后(即sql2的锁释放了才行)才可以继续执行sql2(这个过程是因为sql2的锁没有被释放,导致其他事务在对锁定的行再次加锁时,进入等待锁释放的状态)
    即,事务在执行到第一个for update 的时候这个selet语句拿到的结果记录会加锁,进而阻塞其他想对相同记录加锁的事务,但是其他的事务或者非事务方法,还是能够获取锁定行的记录的(只要不是加锁行为)。

  2. 无事务的情况下:
    for update 不生效,没有锁的效果

锁商品,而不锁库存的优点(之所以这样做因为事务中for update执行后,当其他的事务执行到相同的语句,或者其他事务要对相同的记录加锁时,会进入等待锁释放的状态,进而导致该事务的线程进入等待状态,基于这个特性,可以使事务按你想让事务在哪行代码(在哪行代码加锁,就会在哪进入阻塞状态)进入队列性质的执行顺序):
当用户购买卡券,此时事务首先对卡券信息进行了加锁,进而要去对库存进行扣除的时候(即扣库存之前)
在库存还未扣时,此时如果管理端对库存进行了补充,是可以生效的,因为锁的是商品信息,而不是库存。
即此时无法修改商品信息,其他的都可以。
如果锁的是库存,则只要有用户在购买卡券,这时候就会导致库存无法更改,进而导致管理端在补充库存的时候导致补充失败。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值