欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

乐观锁和悲观锁

程序员文章站 2022-06-02 11:12:39
...

乐观锁和悲观锁

0.锁

并行会导致冲突,冲突需要解决,于是就有了锁。

 

1.悲观锁

悲观锁,pessimistic lock,每次拿数据的时候都认为别人会修改,所以在每次拿数据的时候都会上锁,这样别人想拿这个数据就会block,直到它拿到锁。传统的关系数据库里用到了很多这种锁的机制。

意如其名,悲观锁具有强烈的独占和排他特性。悲观锁的实现,往往依靠数据库提供的锁机制,同时,也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,及时在本系统中实现了加锁机制,也无法保证外部系统不会修改数据。

下面是一个典型的依赖数据库的悲观锁调用:

1 select * from account where name="Erica" for update

 

这条sql锁定了account表中所有符合where条件的记录,在本次事务提交之前,外界无法修改这些记录。

2.乐观锁

乐观锁,optimistic lock,每次拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。

乐观锁的实现是在数据库表加上version版本号的字段,每次修改数据都对version+1,当两个更改请求同时到达数据库,A取到version=1,然后对数据进行修改,修改后将version+1=2写入数据库,此时数据库里的version=1,写入的version大于数据库里的version,乐观锁就认为可以写入,数据库的version被更新为2,;  此时B取到的version也是1,然后对数据修改,修改后version+1=2写入数据库,写入时和数据库的version比对,发现version=2,没有大于数据库中现存的版本号,于是拒绝写入。

乐观锁一般是在应用层实现,在数据库层的代码如下:

 

<update id="updateQuestionLevel">
        UPDATE activity_question
        SET z_index=#{status},
        version=version+1
        WHERE id=#{questionId}
        AND version=#{version}
</update>

  

3.何时使用

乐观锁适用于多读的应用类型,可以提高吞吐量,

乐观锁适用于写比较少的情况,这样可以省去锁的开销,加大系统的吞吐量。

但是如果经常产生冲突,上层应用就会不断地重试,这样就降低了性能,这种情况下悲观锁就比较合适。