数据库悲观锁
Select 。。。 Lock In Share Mode
1:共享锁,在事务内生效
2:给符合条件的是共享锁,其他事务会话同样可以继续给这些行添加共享锁,在锁释放前,其他事务无法对这些进行删除 和修改
3:两个事务同时对一行加共享锁后,无法更新,直到只有一个事务对该行加共享锁
4:如果两个加了共享锁的事务同时更新一行,会发生Deadlock死锁问题
5:某行已有排他锁,无法继续添加共享锁
6:不会阻塞正常读
应用场景:
并发更新会出现问题的场景,如金融账户转账,电商下单的库存扣减,避免最终数字不正确
Select 。。。 For Update
1:排它锁,在事务内生效
2:给符合条件的行添加的排它锁,其他事务无法再加排它锁,在释放前,其他事务无法对这些进行行删除和修改
3:某行已有共享锁,无法继续添加排它锁
4:第一事务对某行加了排它锁,第二个事务继续加排它锁,第二事务需要等待
5:加锁有超时时间
6:不会阻塞正常读
应用场景:
适用于写两张存在关联的表数据,如parent 和 child表,写入child表时需要确保parentId在parent表中已写入数据且不会删除
Update set .... version = version + 1 where version = $version$
1:CAS思路,使用version版本控制,保证同一时间只有一个事务可以更新成功
2:根据影响的行数来判断是否更新成功,更新失败的继续重新获取version值更新,可以设置最大重试次数
应用场景:
电商下单的库存更新:
使用更新语句:update product stock set number = number - 1 where product_id = $productId$ and number-1> = 0
判断更新影响的行数来成功还是失败