mysql的悲观和乐观锁分析

我们在操作数据库的时候,可能会由于并发问题而引起的数据的不一致性(数据冲突),这个时候就有了锁!!!

乐观锁顾明思议,想法很乐观,在更新数据时,认为这波操作不会导致冲突,别的sql也不会对此操作进行更改,所以我线更新数据,等待提交的时候再去判断是否冲突。

乐观锁需要我们自己去实现,数据库设计上,需要给一个状态的字段,比如version,我们需要更新一条数据,那就先去查询这条数据得到里面的version,然后进行更新操作,等到我们提交更新的时候,判断查询出来的version是否与之前的version一致,一致则更新, 同时,version+1,否则失败。

乐观锁一般用于冲突较少的数据操作,如果经常产生冲突,这样反而降低了性能,还不如使用悲观锁比较合理。

举例: 

    下单操作包括3步骤: 

        1.查询出商品信息 select (status,status,version) from t_goods where id=#{id} 

        2.根据商品信息生成订单 

        3.修改商品status为2 update t_goods set status=2,version=version+1 where id=#{id} and version=#{version};

悲观锁:

一般很少用到,因为会造成访问数据库的时间较长,并发性不好,处理少一点的并发还行。

扫描二维码关注公众号,回复: 4760356 查看本文章

悲观锁从数据处理更新开始,就将数据锁住了,更新完后才释放。因此锁的消耗的时间更长。


共享锁其实是悲观锁的一种延伸,其实悲观锁,数据库已经实现了,要想使用共享锁,执行语句后面加上lock in share mode就代表对某些资源加上共享锁了。其它执行语句也可以进行加共享锁。共享锁也就是读锁。指的是对于多个不同的事务,对同一个资源共享同一个锁,可以都有这个锁的钥匙,都能开开。

比如说select * from papapa where id=1 lock in share mode;

在另一边执行,update set name='1' where id=1;

此时就会报错。。

[SQL]update city set name="666" where id ="1";[Err] 1205 - Lock wait timeout exceeded; try restarting transaction

在上一条记录还没有commit之前,这条id=1的记录被锁住了,只有在上一个事务释放掉锁后才能进行操作,或用共享锁才能对此数据进行操作。


排他锁:写锁,对于同一个资源只能有一把锁,不能再加其它的封锁。字面理解就是排除其它的锁。排斥。

在需要执行的语句后面加上for update就可以了。

猜你喜欢

转载自blog.csdn.net/wuhounuanyangzhao/article/details/80576245
今日推荐