在我的Web應用程序中,用戶可以一次插入大量數據,以提高性能我正在使用SqlBulkCopy類。它將多次運行插入兩個不同表中的單個操作。如果用戶取消操作或失敗,那麼我需要數據回滾,以便使用隔離級別快照將所有內容都包含在事務中。SqlBulkCopy在事務內部插入時阻止對錶的任何其他寫入
這是我的理解是,使用快照隔離將允許其他用戶同時寫入/讀取表。但是,當一個數據上傳正在發生時,它將阻止對該表的任何其他寫入,直到整個父事務完成。
下面是一些簡化的代碼,顯示了這個問題。我排除了很多功能,但是這個想法保持不變。我遍歷內存集合中的一些數量,將它們批量複製到一個表中,將它們退回,然後批量複製到另一個表中。
using (var transaction = myDbContext.Database.BeginTransaction(
System.Data.IsolationLevel.Snapshot))
{
var myCollectionOfObjects;
while(!GetData(ref myCollectionOfObjects))
{
SqlBulkCopy bulkCopy = new SqlBulkCopy(myCon, transaction);
//Sets the columns + rows
SetUp(bulkCopy);
bulkCopy.WriteToServer();
//After the bulkcopy operation is complete
// we retrieve the rows inserted and do another bulk copy to a different table
var recentlyAddedRows = GetRecentlyAddedRow();
SqlBulkCopy otherTableBulkCopy = new SqlBulkCopy(myCon, transaction);
SetUpBulkCopyForOtherTable(otherTableBulkCopy);
otherTableBulkCopy.WriteToServer();
}
transaction.Commit();
}
所以,如果一個用戶當前本次交易中,即使是回滾,其他所有寫事務表將被封鎖,以便其他用戶在做同樣的功能或試圖寫入表會受阻。
這是預期的行爲,有沒有辦法解決這個問題?
編輯
通過觀察,由於導致的排他鎖(X)的bulkcopy類SQL應用鎖好像是被在那裏,如果你是將它們插入表對象上設置一次只有一個意圖鎖應用於表(IX)。仍然不確定是否有解決方法,但我認爲這是由於鎖升級。
更改表格索引上的允許頁面鎖定和更改批量副本的批量大小已在我的一些測試中獲得了完全鎖定,但它們很有氣質。
您爲每個事務插入了多少行? – usr
看看SqlBulkCopy的文檔,看起來你需要將事務傳遞給構造函數。 – Chet
你確定你的大容量拷貝參與了交易嗎?myCon從哪裏來?另外[有一個構造函數](https://msdn.microsoft.com/en-us/library/wftd1yfz(v = vs.110).aspx),它接受SqlBulkCopy的事務,不使用它會影響行爲?編輯:另外,因爲它看起來像你使用的實體框架,有擴展[讓你批量插入EF](https://efbulkinsert.codeplex.com/),它可能會比SqlBulkCopy稍慢,但它可以讓你爲單行和批量行保留單個模型。 –