ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

悲观锁和乐观锁

2019-10-24 15:57:13  阅读:272  来源: 互联网

标签:事务 读取数据 写入 乐观 修改 Adam 悲观 Barbara


我们通常希望避免在两个并行事务中产生如下情形:

Adam的事务读取数据 X
Barbara的事务读取数据 X
Adam的事务修改数据 X,并将其修改为 XA
Adam的事务写入数据 XA
Barbara的事务修改数据 X,并将其修改为 XB
Barbara的事务写入数据 XB
结果是,Adam所做的修改完全被Barbara所覆盖掉了,但是Barbara对此却毫不知晓。像这样的情况通常被称为“脏读”。显然,我们希望的结果是Adam写入 XA,而Barbara需要在写入 XB之前检查对 XA 的修改。


乐观锁的工作原理 (Optimistic Locking )
乐观锁基于的假设是实际中冲突很少发生,即使发生,抛出一个错误也比想办法避免它们更容易接受和简单。在乐观锁中,允许一个事务正确完成,但另一个事务需要抛出异常并回滚,并且必须被重新执行或者丢弃。

我们还以Adam和Barbara为例,下面是一个使用乐观锁可能发生的情形:

Adam的事务读取数据 X
Barbara的事务读取数据 X
Adam的事务修改数据 X,并将其修改为 XA
Adam的事务写入数据 XA
Barbara的事务修改数据 X,并将其修改为 XB
Barbara的事务试图写入数据 XB,但是收到一个错误
Barbara需要读取数据 XA(或者重新开始一个新的事务)
Barbara的事务修改数据 XA,并将其修改为 XAB
Barbara的事务写入数据 XAB
如你所见,Barbara被强制要求检查Adam的修改,并且她可以选择继续修改Adam的结果并保存(合并修改)。最后的数据将同时包括Adam和Barbara的修改。

乐观锁完全由JPA控制。它需要在DB表中额外存储一个版本号列。它完全依靠于底层用来存储关系型数据的DB引擎来工作。

 

悲观锁的工作原理(Pessimistic Lock)
对于某些人来说,悲观锁更容易接受。当事务需要修改一个可能被其他事务同时修改的实体时,事务会发起一个命令将实体锁住。所有的锁会持续到事务结束后再自动释放。

使用悲观锁的情形可能如下所示:

Adam的事务读取数据 X
Adam的事务锁住 X
Barbara的事务希望读取数据 X,但是因为 X 已经被锁住,只好等待
Adam的事务修改数据 X,并将其修改为 XA
Adam的事务写入数据 XA
Barbara的事务读取数据 XA
Barbara的事务修改数据 XA,并将其修改为 XAB
Barbara的事务写入数据 XAB
如你所见,Barbara又一次被强制的写入 XAB,同时也包含了Adam的修改。但是,这个方案与乐观锁完全不同——Barbara需要等待Adam的事务完成以后才能够读取数据。更甚的是,为了让该场景正确工作,我们需要在两个事务中都手动发起一个lock命令。(因为我们并不确定那个事务先运行,所以两个事务都需要在修改数据前先进行锁定)虽然乐观锁要为每个实体增加一个版本列,比悲观锁工作略多,但是之后我们不需要再在事务中发起锁操作了。JPA会自动完成所有的检查,我们只需要处理可能的异常即可。

悲观锁使用底层数据库提供的锁机制来锁住表中已有的记录。JPA需要知道如何触发这些锁,并且尚不能完全支持某些数据库。

标签:事务,读取数据,写入,乐观,修改,Adam,悲观,Barbara
来源: https://www.cnblogs.com/longyao/p/11732627.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有