2013-08-07 23 views
0

爲了防止出現併發錯誤,我決定將所有的sql調用(這些都是在存儲過程中)sql語句(所有的crud操作,比如update/insert/upserts,甚至只是表格讀取)是否在ISOLATION LEVEL SERIALIZABLE中包裝所有的sql調用?刪除所有併發問題?

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
開始TRAN

--sqlstatements here 

OPTION(MAXDOP 1)

COMMIT TRAN

讓我們說我不關心表現。我只想防止由兩個或更多併發線程訪問相同數據庫引起的約束違規和死鎖。

這是否有效地消除所有死鎖以及競爭條件引起的約束問題?

如果我已經將調用包裝在可序列化事務中,是否還需要爲CUD函數顯式使用(保持鎖定,更新鎖定)?

+0

假設數據庫中存在多個對象,仍然可能存在死鎖。 –

+0

嘗試[this](http://nexussharp.wordpress.com/2012/01/30/deadlock-heaven-serializable-isolationlevel/)並親自查看。 – OzrenTkalcecKrznaric

回答

0

可串行化隔離級別可以防止所有三個已知的併發問題,因爲可序列化級別應用範圍鎖定,因此您不能使用事務範圍修改行。 它防止(但可能造成死鎖):

Dirty Reads當一個事務讀取由另一個未提交的事務寫入的數據時發生。髒讀取的危險是另一個事務可能永遠不會提交,從而使原始事務保留「髒」數據。

Non-repeatable Reads當一個事務嘗試訪問相同的數據兩次,第二個事務修改第一個事務的讀取嘗試之間的數據時發生。這可能會導致第一個事務爲相同的數據讀取兩個不同的值,導致原始讀取不可重複。

Phantom Reads當一個事務訪問多個數據範圍且第二個事務插入或刪除行時在第一筆交易的讀取嘗試之間的範圍內。這可能會導致「幻影」行從第一個交易的角度出現或消失。

1

這取決於你的意思是「併發問題」。如果在此處包含死鎖,那麼您可能仍然需要在查詢中包含鎖定提示(例如:updlock

+0

不能保證UPDLOCK可以防止所有的死鎖 – OzrenTkalcecKrznaric

+1

@OzrenTkalčecKrznarić不,但問題是「可序列化防止併發問題」,答案是「否」 – podiluska

+0

隨時在您的答案中寫入。 – OzrenTkalcecKrznaric

相關問題