3

衆所周知,有兩種鎖定策略:Optimistic vs. Pessimistic locking使用樂觀鎖定時可能會出現死鎖嗎?

悲觀鎖定是,當你鎖定該記錄爲您獨家使用 ,直到你完成它。它比 樂觀鎖定具有更好的完整性,但要求您注意應用程序設計以避免Deadlocks

而且knonw,即Optimistic Concurrency Control是不一樣的Multi Version Concurrency Control(Oracle或MSSQL快照/ MVCC-RC):Optimistic vs Multi Version Concurrency Control - Differences?

但是,如果在這兩個使用OCC(Optimistic Concurrency Control)兩筆交易之間可以發生死鎖?

我們可以說樂觀鎖定通過降低一致性來減少死鎖的可能性嗎?只有每次更新都在單獨的事務中,那麼死鎖的可能性爲0%,但這是最小的一致性。

回答

3

當然。

死鎖只是意味着線程A擁有一個鎖,線程B正在等待,而B持有A正在等待的鎖。如果您的應用程序不是按照相同順序鎖定資源的,則無論您的鎖定策略如何,都很容易死鎖。

想象一下,線程A和B都希望更新父表和子表中的特定行。線程A首先更新父行。線程B首先更新子行。現在,線程A嘗試更新子行並發現自己被B阻止。同時,線程B嘗試更新父級並發現自己被A阻止。您有一個死鎖。

如果您在Oracle中擁有一致的鎖定資源順序(即始終在子級之前鎖定父級),則不管您的鎖定策略如何,都不會發生死鎖。您通常不會在SQL Server中導致死鎖,但是在SQL Server中升級行級鎖的可能性不足以確定。

+0

謝謝!因此Oracle數據庫永遠不會升級鎖。鎖定升級大大增加了死鎖的可能性。這是否意味着死鎖是多版本併發的另一個差異樂觀併發?但目前,在完成樂觀併發時 - 讀取 - 檢查 - 修改行時,我們是否使用鎖定?或者每次交易只能有一個鎖定,所以不能成爲死鎖。 – Alex

+1

@亞歷山大 - 我不確定我是否瞭解跟進。爲了更新一行,你必須鎖定它。樂觀和悲觀鎖定之間的區別在於,您是否悲觀地鎖定行以防萬一您可能會更新它,或者樂觀地等待,直到您知道要更新它以獲取鎖定。您可以編寫一個應用程序,將每次更新作爲單獨的事務處理。這樣可以減少死鎖,但對於數據一致性來說會很糟糕。 –

+0

是的,謝謝,這就是我想知道的。我們可以說樂觀鎖定通過降低一致性來減少死鎖的可能性嗎?只有在單獨事務中的每次更新時,死鎖的可能性都是0%,但這是最小的一致性。使用一定數量的樂觀方法,我們可以在死鎖和一致性之間取得必要的平衡。 – Alex

1

恐怕您在樂觀併發控制的定義中必須非常精確。在Bernstein,Goodman和Hadzilacos的經典定義中,樂觀併發控制允許線程「虛擬」獲取鎖,繼續更新,然後在事務嘗試提交時檢查一致性違規。如果發生一致性違規,則該事務將被迫中止並重新提交。在這個定義下,不清楚死鎖是如何發生的,因爲線程「永不」被阻塞等待鎖定。樂觀併發控制的經典定義並不容易實現。然而,最近在硬件事務內存方面的工作正在開啓一些可能性,並對這個老問題提出一些看法。

+0

謝謝!但是使用硬件事務存儲器實現的樂觀併發控制的經典定義 - 它是否可以具有屬性可組合性? https://en.wikipedia.org/wiki/Software_transactional_memory#Composable_operations – Alex

+0

此外,使用「可調整隔離級別」時出現死鎖的可能性最小,當任何修改僅在事務提交後纔可見時,Tom Kyte說「可串行化是實現高吞吐量和更快響應時間的一種方式「,從中可以得出線程碰撞較少的結論。 https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:12684560615138這是真的,通過使用OCC可以在MVCC中只實現可調整的隔離級別,或者也可以其他:閱讀提交,可重複閱讀,快照? – Alex