5

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

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

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

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

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

4

2 回答 2

7

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

于 2016-12-01T11:19:37.987 回答
6

当然。

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

假设线程 A 和 B 都想更新父表和子表中的特定行。线程 A 首先更新父行。线程 B 首先更新子行。现在线程 A 尝试更新子行并发现自己被 B 阻塞。同时,线程 B 尝试更新父行并发现自己被 A 阻塞。你有一个死锁。

如果您在Oracle 中锁定资源的顺序一致(即始终在子项之前锁定父项),则无论您的锁定策略如何,都不会出现死锁。您通常不会在 SQL Server 中遇到死锁,但在 SQL Server 中行级锁升级的可能性使得这不太确定。

于 2016-08-14T21:50:58.743 回答