簡體   English   中英

與多個表進行交易時出現死鎖

[英]Deadlock on transaction with multiple tables

我的情況很常見:我有一個存儲過程,需要更新多個表。 如果更新之一失敗-應該回滾所有更新。 海峽前進的答案是將所有更新包含在一個事務中,然后回滾。 但是,在像我們這樣的系統中,這將導致並發問題。 當我們將更新分為多個短事務時-之前每秒獲得約30個並發執行的吞吐量,並且開始出現死鎖問題。 如果我們將它放到一個涵蓋所有事務的事務中,則在出現死鎖之前,每秒並發速度約為2。

在我們的例子中,我們在每個短事務之后放置一個try-catch塊,並手動刪除/更新先前的更改。 因此從本質上講,我們以一種非常昂貴的方式來模仿事務行為...它工作正常,因為其編寫得很好,並且沒有得到很多“回滾” ...這種方法根本無法解決的一件事是來自網絡的命令超時情況服務器/客戶端。

我已經閱讀了許多形式和博客的大量文章,並通過MSDN進行了掃描,但找不到合適的解決方案。 許多人提出了這個問題,但是我還沒有看到一個好的解決方案。

問題是:此問題是否有解決方案,可以穩定地回滾更新多個表,而無需在長事務的整個過程中在所有行上建立排他性鎖定。

假定這不是優化問題。 這些表幾乎處於最大優化狀態,並且只要沒有死鎖就可以提供很高的吞吐量。 沒有表鎖/頁面鎖等。所有行鎖都更新-但是,當您有這么多並發會話時,其中一些需要更新同一行...

它可以通過SQL,客戶端C#,服務器端C#(擴展SQL Server?)來實現。 在我沒有找到的任何書籍/博客中都有這樣的解決方案嗎?

我們正在使用SQL Server 2008 R2,並將.NET客戶端/ Web服務器連接到它。 代碼示例:

創建過程sptest開始事務更新表1更新表2提交事務

在這種情況下,如果sptest運行兩次,則第二個實例將無法更新表1,直到實例1提交為止。 與此相比

創建sptest2更新表1更新表2

Sptest2具有更高的吞吐量-但它有機會破壞數據。 這就是我們要解決的問題。 有沒有理論上的解決方案?

謝謝,JS

我想說,您應該更深入地了解死鎖發生的原因。 可能您應該更改更新順序以避免它們。 也許有些索引是“有罪的”。

如果其他事務可以更改數據,則無法回滾更改。 因此,您需要對它們進行更新鎖定。 但是您可以使用快照隔離級別來允許在更新提交之前進行一致的讀取。

對於所有大多數是靜態的或具有較高概率的內部聯接表,通過使用臟數據不會影響查詢,則可以應用:

INNER JOIN LookupTable (with NOLOCK) lut on lut.ID=SomeOtherTableID

這將告訴查詢我不在乎對SomeOtherTable所做的更新

在大多數情況下,這可以減少您的問題。 對於更困難的死鎖,我實現了一個死鎖圖,該死鎖圖在死鎖發生時生成並通過電子郵件發送,其中包含該死鎖的所有詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM