2011-08-22 27 views
2

我有一個存儲過程插入到單個事務中的多個表中。我知道事務可以通過在錯誤,電源故障等後面回滾來保持數據在非併發情況下的一致性,但是如果其他代碼在我提交事務之前從這些表中選擇,是否可能選擇不一致的數據?交易會阻止其他代碼讀取不一致的數據嗎?

基本上,你可以選擇未提交的交易嗎?

如果是這樣,那麼人們通常會如何處理這個問題?

+0

是不是在存儲過程中發生的東西放在隱藏的交易無論如何? – Johan

回答

7

這取決於讀取查詢的隔離級別而不是事務。這可以在連接上集中設置或在SELECT提示中提供。

參見: 連接側:http://msdn.microsoft.com/en-us/library/system.data.isolationlevel.aspx

數據庫側:http://msdn.microsoft.com/en-us/library/ms173763.aspx

+0

+1。基本上是的,有一種方法可以讀取無限數據,如果你想。必須明確設置。 – TomTom

+0

非常好,還有一個問題:從事務內部我可以從另一個表中選擇以前插入到事務處理中的其他表中嗎? –

+1

@nw:是的 - 除非你的DBMS壞了。您的交易應該能夠看到它所做的更改。 –

1

如已經由Aliostad提到的,這取決於所選擇的isolation level。維基百科文章有不同常見場景的例子。

所以是的,你可以選擇獲取未提交的數據,但只能通過選擇。我從來沒有這樣做,我不得不承認這個想法對我來說似乎有點危險。但是可能有合理的用例。

+3

當然,經常彙總數百萬行的報告查詢不需要事務一致,想象一下,爲大量網站收集網絡流量點擊的表格。我應該等待多久才能獲得100%準確的數量(不要介意我正在放慢其他讀者和作家的速度),當球場足夠好的時候(例如,我們有500萬次點擊還是正好5,123,421點擊數)? –

+0

@Aaron感謝一個合理的髒讀例子的好例子! – fvu

+1

當然,另一件事情是,當試圖爲桌子計數時,出於一些相同的原因,可能根本不需要觸摸桌子。從整個表的sys.dm_db_partition_stats中提取計數值,或者如果它是篩選索引支持的數據的子集,可以高效得多,只要您知道如果有任何活動交易。 –

0

擴展Aliostad的回答是:

默認情況下,其他的閱讀進程不會閱讀正在改變數據(未提交的,又名「髒讀」)。這適用於所有客戶端和驅動程序

您必須故意使用NOLOCK提示或更改隔離級別來允許「髒讀」來覆蓋此默認值。