mysql乐观锁和悲观锁

文章非原创,而是来自于对网上文章的阅读理解和记录。感谢原作者们。

悲观锁

用sql来说明大概思路:

set autocommit=false;
start transaction;
select goods_status from t_goods where goods_id=1 for update;
insert into t_orders (id, goods_id) values (null,1);
update t_goods set goods_status = true where goods_id=1;
commit;

开启事务之后,利用mysql默认的【可重复读】事务隔离级别的规则:读操作不允许写,写操作不允许读写。事务内对数据重复读出来的值是一致的。
select for update,这样其他事务就不可以对good_id=1这个数据读写了,起到了一个排它锁的作用。
然后插入订单t_orders,同时修改商品状态goods_status为true已下单。操作结束以后commit提交事务。事务结束。
需要注意的是select for update操作不当会引发锁表,必须严格在where条件里指定主键或索引等于匹配才行,这时候才是期望的行锁
如果主键或索引不明确等于、或条件不是主键或索引、或不加任何条件,都是会锁整个表的表锁

乐观锁

最常见的就是在表里边加一个version字段,要做修改之前先查出来,然后更新数据的时候version+1同时where条件里把version带上。
如果更新了0条数据,说明这时候version变了,数据被修改了,更新失败。这就是乐观锁的思路。跟CAS是一样的思路。

SQL和伪代码如下:

select goods_status, version from t_goods where goods_id = 1;

update t_goods set goods_status=true , version = 2 where goods_id=1 and version = 1;

if update 1 then 
    insert into t_orders (id, goods_id) values(null, 1);
else
    已售出,下订单失败
end;
参考:

https://www.iteye.com/blog/chenzhou123520-1860954
https://www.iteye.com/blog/chenzhou123520-1863407

你可能感兴趣的:(mysql乐观锁和悲观锁)