將死結數量降至最低

雖然死結無法完全避免,但是遵守某些程式碼撰寫的慣例可以將死結產生的機會降到最低。將死結降至最低可以提高交易的產能並降低系統負擔,因為較少的交易需要:

  • 回復,將交易所進行的工作全部恢復。

  • 由應用程式重新送出,因為發生死結時已將交易回復。

若要協助將死結降至最低:

  • 以相同的順序來存取物件。

  • 在交易中避免使用者互動。

  • 將交易維持在單一批次中且愈短愈好。

  • 使用較低的隔離等級。

  • 使用資料列版本控制基礎的隔離等級。

    • 將 READ_COMMITTED_SNAPSHOT 資料庫選項設為 ON,讓讀取認可交易使用資料列版本控制。

    • 使用快照隔離。

  • 使用繫結連接。

以相同的順序來存取物件

如果所有同時發生的交易都以相同的順序來存取物件,就比較不會發生死結。例如,如果同時發生的兩筆交易都取得 Supplier 資料表的鎖定,再取得 Part 資料表的鎖定,其中一筆交易便被封鎖於 Supplier 資料表直到另一筆交易完成為止。第一筆交易認可或回復之後,第二筆才會繼續,這樣就不會發生死結。使用預存程序來進行所有的資料修改動作可將物件的存取順序標準化。

顯示死結避免的圖表

在交易中避免使用者互動

避免撰寫包含使用者互動的交易,因為沒有使用者介入的批次執行速度比使用者必須對查詢做出手動回應的批次更快,例如對應用程式所要求的參數提示做出回覆。例如,交易如果正在等候使用者輸入,而使用者去用餐,或甚至回家渡假,交易就會被使用者延遲而無法完成。如此便會降低系統產能,因為交易所持有的任何鎖定只有在交易被認可或回復之後才會釋放。即使並未發生死結的狀況,要存取相同資源的其他交易還是會被封鎖而等待交易完成。

將交易維持在單一批次中且愈短愈好

死結通常會在許多長時間執行的交易同時執行於相同的資料庫時發生。交易的時間愈久,持有的獨占或更新鎖定就愈久,因而封鎖了其他的活動並導致發生死結狀況的可能性。

將交易維持在單一批次中可降低交易期間的網路來回次數,因而降低了完成交易以及釋放鎖定的延遲可能性。

使用較低的隔離等級

判斷是否可以較低的隔離等級執行交易。實作讀取認可讓交易可以對另一筆交易先前讀取 (未修改) 的資料進行讀取,而不必等待前一筆交易完成。使用較低的隔離等級 (如讀取認可),則持有共用鎖定的期間比使用較高的隔離等級(如序列化) 更短。如此就可減少鎖定爭用。

使用資料列版本控制基礎的隔離等級

當 READ_COMMITTED_SNAPSHOT 資料庫選項設為 ON 時,在讀取認可隔離等級下執行的交易會使用資料料版本控制,而非讀取作業期間的共用鎖定。

[!附註]

部份應用程式則依靠讀取認可隔離的鎖定和鎖定行為。對於這些應用程式,在啟用選項之前,需要進行部份變更。

快照隔離也使用資料列版本控制,不使用讀取作業期間的共用鎖定。ALLOW_SNAPSHOT_ISOLATION 資料庫選項必須設為 ON,交易才能在快照隔離下執行。

實作這些隔離等級可將讀取和寫入作業之間發生的死結降到最低。

使用繫結連接

使用繫結連接,則同一個應用程式所開啟的二或多個連接可以互相合作。如果先前由主要連接獲得鎖定,則會讓次要連接持有獲得的鎖定,反之亦然。所以它們不會互相鎖定。