我懷疑我不完全理解發生了什麼或發生了一些奇怪的事情。 (第一種情況的可能性更大,我猜。)SQL中的快照隔離/代碼阻塞讀取
大圖片:
- 我想有一個Web服務執行某些操作異步,因爲他們可能會非常耗時,我不希望客戶端等待操作完成(只需查詢結果就可以看到操作完成)。
- 異步代碼被封裝在一個事務中 - 萬一出現問題,我希望能夠回滾任何更改。
- 不幸的是,異步代碼的最後一步是調用查詢同一數據庫的不同服務。
- 儘管在Snapshot事務中包裝整個事件,但最後一步失敗,因爲該服務無法從數據庫中讀取。
- 對於這個問題,雖然異步操作正在進行中,但我無法從數據庫執行簡單的SELECT語句。
這裏的(使用實體框架5模型第一),這我目前使用測試出交易代碼示例:
using (var transaction = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.RequiresNew, new System.Transactions.TransactionOptions() { IsolationLevel = System.Transactions.IsolationLevel.Snapshot }))
{
var db = new DataModelContainer();
Log test = new Log();
test.Message = "TEST";
test.Date = DateTime.UtcNow;
test.Details = "asd";
test.Type = "test";
test.StackTrace = "asd";
db.LogSet.Add(test);
db.SaveChanges();
using (var suppressed = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Suppress))
{
var newDb = new DataModelContainer();
var log = newDb.LogSet.ToArray(); //deadlock here... WHY?
}
test = db.LogSet.Where(l => l.Message == "TEST").Single();
db.LogSet.Remove(test);
db.SaveChanges();
transaction.Complete();
}
的代碼創建數據庫(一個簡單的日誌條目是的,我現在在玩耍,所以價值是垃圾)。我已經將SQL數據庫設置爲允許快照隔離,並且對於我的知識,仍應該允許讀取(這些正在使用新的抑制事務和新的DataModelContainer
在此代碼中進行測試)。但是,我無法在被抑制的事務或SQL Management Studio中查詢LogSet
- 整個表已被鎖定!
那麼...爲什麼?如果事務範圍被定義爲這樣,爲什麼它被鎖定?我也嘗試過其他隔離級別(如ReadUncommited
),我仍然無法查詢表格。
是否有人可以提供這種行爲的解釋?
是快照隔離在你的數據庫中啓用? 「快照隔離必須通過在事務中使用ALLOW_SNAPSHOT_ISOLATION ON數據庫選項之前啓用」 – Moho
@Moho是的。 *我已將SQL數據庫設置爲允許快照隔離*。無論如何,當使用OTHER隔離模式時(比'Serializable'限制更少),問題依然存在,比如'ReadUncommited',並且這個甚至不需要在SQL服務器上啓用快照隔離! – Shaamaan