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

时间:2016-08-14 21:32:22

标签: sql-server oracle locking optimistic-locking pessimistic-locking

众所周知,有两种锁定策略:Optimistic vs. Pessimistic locking

  

悲观锁定是指锁定记录供您独家使用   直到你完成它。它的完整性要好得多   乐观锁定,但要求你小心你的   应用程序设计以避免Deadlocks

同样知道,Optimistic Concurrency ControlMulti Version Concurrency Control(Oracle或MSSQL-Snapshot / MVCC-RC)不同:Optimistic vs Multi Version Concurrency Control - Differences?

但如果在两个事务中使用OCC(Optimistic Concurrency Control),可能会在两个事务之间发生死锁吗?

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

2 个答案:

答案 0 :(得分:3)

不确定

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

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

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

答案 1 :(得分:2)

我担心你在乐观并发控制的定义中必须非常精确。在Bernstein,Goodman和Hadzilacos的经典定义中,乐观并发控制允许线程“虚拟地”获取锁,继续更新,然后在事务尝试提交时检查一致性违规。如果发生一致性违规,则强制事务中止并重新提交。在这个定义下,不清楚死锁是如何发生的,因为线程被“永远”阻塞等待锁定。乐观并发控制的经典定义实际上并不容易实现。然而,最近关于硬件事务存储器的工作正在打开一些可能性,并对这个老问题有所了解。