FOR UPDATE
中文直译的意思是:用于更新。 理解:这次查询的数据我要用于更新操作,所以麻烦Mysql帮我加锁,其他进程在我更新完成之前不能发起for update请求(可以发起普通select请求, 用于前端展示) 用途:防止高并发情况下,比如用户连续快速点击两次购买,导致商品数量超卖 为负数等情况
必要条件
- mysql innodb引擎
- 在事务中启用for update(直到commit 或者rollback 此次更新操作结束 释放锁)
- mysql暂无for update nowait 需要封装,增加控制超时时间的逻辑,这样子伪nowait
- select命中索引或者主键,则为行锁,没有命中则为表锁(需要注意 避免影响业务)
测试步骤
1.一个连接A 发起事务,执行select for update
START TRANSACTION; select * from test where id = "Auth" for update;
2.另一个连接B 发起普通select请求,正常返回结果 3.连接B 发起select for update请求,由于第一个步骤的事务还没有结束,所以不能获取,会一直堵塞,直到超时 或者锁被释放后返回 4.没有nowait 可以封装如下逻辑
function testNowait(){ // 执行sql 超时时间更改为0.5s // 执行for update // 0.5s后则返回失败(默认可能长达1分钟) // 恢复为默认的超时时间,避免影响其他sql执行 }