当前位置: 首页 > 知识库问答 >
问题:

使用乐观锁定时是否会出现死锁?

金赤岩
2023-03-14

众所周知,有两种锁定策略:乐观锁定和悲观锁定

悲观锁定是锁定记录供您独占使用,直到您使用完它。它比乐观锁定具有更好的完整性,但是需要您小心应用程序设计以避免死锁。

也知道,乐观并发控制与多版本并发控制(Oracle或MSSQL-Snapshot/MVCC-RC)不同:乐观与多版本并发控制-差异?

但是,如果在两个事务中都使用OCC(乐观并发控制),会在两个交易之间发生死锁吗?

我们可以说乐观锁通过减少一致性来减少死锁的可能性吗?并且只有当每个更新都在一个单独的事务中时,死锁的可能性才是0%,但这是最小的一致性。

共有3个答案

汝跃
2023-03-14

不会。在乐观锁定中,您乐观地假设“锁定”的键在事务提交之前不会改变。如果在提交事务之前更改了“锁定”键,则事务将被还原并重试。因为乐观锁是100%非阻塞的,所以没有死锁。由于这个原因,我甚至认为乐观锁有时比悲观锁更安全。

勾安翔
2023-03-14

当然。

死锁只是意味着线程A持有线程B正在等待的锁,而线程B持有线程A正在等待的锁定。如果应用程序的设计不是在任何地方以相同的顺序锁定资源,那幺不管锁定策略如何,死锁都很容易。

假设线程A和线程B都希望更新父表和子表中的特定行。线程A首先更新父行。线程B首先更新子行。现在线程A尝试更新子行,发现自己被B阻止。同时,线程B尝试更新父行,发现自身被A阻止。您有死锁。

如果在Oracle中锁定资源的顺序是一致的(即总是先于父锁先于子锁),那么无论您的锁定策略如何,您都不会遇到死锁。在SQLServer中通常不会遇到死锁,但是在SQLServer中行级锁升级的可能性使得这一点不太确定。

常明亮
2023-03-14

恐怕您必须非常精确地定义乐观并发控制。在Bernstein、Goodman和Hadzilacos的经典定义中,乐观并发控制允许线程“虚拟地”获取锁,继续更新,然后在事务尝试提交时检查一致性冲突。如果发生一致性冲突,事务将被迫中止并重新提交。根据这个定义,不清楚死锁是如何发生的,因为线程在等待锁时“从不”被阻塞。乐观并发控制的经典定义在实际中不易实现。然而,最近在硬件事务性内存方面的工作打开了一些可能性,并为这个老问题提供了一些视角。

 类似资料:
  • 我们有一个系统,我们偶尔会得到一个乐观的锁定异常。我们在代码中已经解决了这个问题,但现在我正在查看JPA 2,并看到它有一个用于处理这个问题的注释(@版本) 我们的问题是,一个表上有多个事务,如果表锁已满,则即使未对相同的记录进行更改,也会导致乐观锁定异常。 我们在JBoss 4.2服务器上使用hibernate,数据库可以是MySQL或SQL服务器。 如果改为使用@Version,这会在两个数据

  • 在多用户环境中,在同一时间可能会有多个用户更新相同的记录,会产生冲突,解决方案有两种:乐观锁、悲观锁。 悲观锁在这里不讲,自行Google。 乐观锁假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性,不完整则更新失败。 乐观锁实现方式 使用整数表示数据版本号.更新时检查版本号是否一致,如果相等,则更新成功,且版本号+1.如果不等,则数据已经被修改过,更新失败。 使用时间戳来实现。 本质上也

  • 问题内容: 我试图按顺序实施乐观锁定,以避免丢失更新情况。在我的应用程序中,当两个用户获取相同的记录,而第一个用户通过一些更改对其进行更新时。查看相同记录的第二个用户看不到此更改,并且他自己进行了一些更改并更新了该记录。因此,第一人称更改丢失。为了防止这种情况,我写了以下内容,但问题仍然存在。我是这个概念的新手,无法发现问题。 我试图通过阅读doc 11.3.4 来实现这一目标。自定义自动版本控制

  • 我对JPA中乐观锁定的好处有点困惑。 我在版本化实体表上用两个线程和一行进行了测试。 这是我的发现: 第二次测试。请注意select语句的添加。 我真的没想到在使用乐观锁定时会发生任何阻塞,但是我的理解是,这里必须有一个数据库事务,以便从 select 语句返回正确的数据。 由于JPA似乎只在绝对必要时输入数据库事务,谁能解释一下乐观锁定的好处是什么?

  • 问题内容: 我找不到有关MySQL中乐观锁定的任何详细信息。我读到开始事务使两个实体上的更新保持同步,但是,它不会停止两个用户同时更新数据而引起冲突。 显然乐观锁定会解决这个问题吗?这在MySQL中如何应用。是否有SQL语法/关键字呢?还是MySQL具有默认行为? 谢谢你们。 问题答案: 关键是,乐观锁定不是数据库功能,不适用于MySQL或其他功能:乐观锁定是一种使用带有标准指令的DB进行的实践。

  • Sequelize 内置支持通过模型实例版本计数进行乐观锁定. 乐观锁定默认情况下处于禁用状态,可以通过在特定模型定义或全局模型配置中将 version 属性设置为 true 来启用. 有关更多详细信息,请参见模型基础. 乐观锁定允许并发访问模型记录以进行编辑,并防止冲突覆盖数据. 它通过检查自从读取以来另一个进程是否对记录进行了更改,并在检测到冲突时抛出 OptimisticLockError