乐观锁和悲观锁

乐观锁和悲观锁

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.何时使用

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

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

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

原文地址:https://www.cnblogs.com/AaronCui/p/4904522.html