如果SELECT 后面若要UPDATE 同一个表数据的相关操作,最好使用SELECT ... FOR UPDATE。
一:举例说明
假设商品表单test_leyangjun 内有一个存放商品库存的num字段,一个id主键 ,在生成订单前须先确定num>0 ,然后才把数量更新。代码如下(比如现在的库存:num=3对应的id=3,现在生成一个订单需要对库存做扣减少):
SELECT num FROM test_leyangjun WHERE id=3; UPDATE test_leyangjun SET num = num-1 WHERE id=3;
确实以上sql看上去没啥问题,逻辑也很明确就是做一个库存更新操作,但是在高并发请求的时候上面的sql就会暴露出对应问题,啥问题呢?就是在高并发请求的时候,如果我们需要在num>0 的情况下才能扣库存,假设程序在第一行SELECT 读到的num=3 ,但当MySQL 正准备要UPDATE 的时候,可能已经有人把库存扣成 “2|1|0 ”了,但是程序是不知道的咔嚓一下就执行UPDATE。因此必须透过的事务机制来确保读取及提交的数据都是正确的。
1: 每次操作开启事务
2:使用MySql -> SELECT ... FOR UPDATE机制
SELECT num FROM test_leyangjun WHERE id=3 FOR UPDATE; UPDATE test_leyangjun SET num = num-1 WHERE id=3;
二:注意
1:以上加上锁和for update其是在高并发的时候其实还是有低风险的数据不一致情况,在使用事务更新数据的时候加上历史数据值作为查询条件,改造后应该是这样,已避免风险存在
SELECT num FROM test_leyangjun WH

在高并发环境中,使用SELECT ... FOR UPDATE结合事务处理可以确保数据一致性。通过FOR UPDATE锁,可以实现行级锁定,防止并发更新导致的问题。文章详细介绍了FOR UPDATE在不同场景下的锁行为,包括主键和普通索引的区别,以及如何避免数据不一致的风险。
最低0.47元/天 解锁文章
624





