理解数据库之悲观锁和乐观锁


数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。而乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段。


概念

乐观锁和悲观锁可以说是一种思想,一种人们为了解决并发控制带来的问题而定义好的策略。这里需要注意的是千万不能将乐观锁和悲观锁的概念狭义地理解为数据库中提供的锁机制,例如行锁、表锁、共享锁、排他锁。其实,我们应该知道的是悲观锁正是利用了数据库本身提供的锁机制来实现的。

悲观锁

悲观锁如其名字一般,即当数据被外界修改时保持悲观态度。当数据处理中,将数据处于锁定状态。而悲观锁的实现往往是依靠着数据库提供的排他锁锁机制。

悲观锁适用于数据争用激烈的环境,以及发生并发冲突时使用锁保护数据的成本要低于回滚事务的成本的环境中。

悲观锁的流程:
  1. 在对任意记录进行修改前,先尝试对该记录加上排他锁。
  2. 如果加锁失败,说明该记录正在被修改。那么继续等待或者抛出异常,具体的响应方式由开发者自定义。
  3. 如果加锁成功,那么就可以对该记录进行修改了,事务完成后即解锁。
  4. 期间如有其他事务对其进行修改或者加锁的操作,都会等待我们解锁或者抛出异常。
优点与不足

优点:悲观锁采用了“先取锁再访问”的保守策略,为数据处理的安全提供了保障。
不足在于:

  1. 在效率方面,处理加锁的机制会使数据库产生额外的开销,还有可能产生死锁的风险。
  2. 在只读型事务的处理中由于不会引起冲突,也没必要使用锁,只会增加系统的开销。
  3. 会降低了并行性,一个事务如果锁定了某行数据,其他事务就必须等待该事务处理完才可以处理那行数。
乐观锁

乐观锁假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回滚。

乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。

相对于悲观锁,在对数据库进行处理的时候,乐观锁并不会使用数据库提供的锁机制。一般的实现乐观锁的方式就是记录数据版本

数据版本,为数据增加的一个版本标识。当读取数据时,将版本标识的值一同读出,数据每更新一次,同时对版本标识进行更新。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的版本标识进行比对,如果数据库表当前版本号与第一次取出来的版本标识值相等,则予以更新,否则认为是过期数据。
实现数据版本有两种方式,第一种是使用版本号,第二种是使用时间戳

优点与不足

乐观并发控制相信事务之间的数据竞争(data race)的概率是比较小的,因此尽可能直接做下去,直到提交的时候才去锁定,所以不会产生任何锁和死锁。但如果直接简单这么做,还是有可能会遇到不可预期的结果,例如两个事务都读取了数据库的某一行,经过修改以后写回数据库,这时就遇到了问题。

参考链接:

深入理解乐观锁与悲观锁:https://www.open-open.com/lib/view/open1452046967245.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值