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

Could there be a deadlock when using optimistic locking?

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

Pessimistic Locking is when you lock the record for your exclusive use until you have finished with it. It has much better integrity than optimistic locking but requires you to be careful with your application design to avoid Deadlocks.

也知道,Optimistic Concurrency Control is not the same as Multi Version Concurrency Control (Oracle or MSSQL-Snapshot/MVCC-RC): Optimistic vs Multi Version Concurrency Control - Differences?

但是如果在两个事务中都使用 OCC(Optimistic Concurrency Control) 是否会在两个事务之间发生死锁?

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

当然可以。

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

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

如果您在 Oracle 中有一致的锁定资源顺序(即总是先锁定父资源再锁定子资源),则无论您的锁定策略如何,都不会出现死锁。您通常不会在 SQL 服务器中遇到死锁,但行级锁在 SQL 服务器中升级的可能性使这种情况变得不确定。

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