2014-02-17 51 views
3

我有每5分鐘運行一次的進程A,需要在表「EventLog」中寫入一些內容。這一整天都在工作,但是晚上還有另一個B進程,需要從這個表中刪除大量的舊數據。該表具有數百萬行(包括斑點)和許多相關表(由級聯刪除),因此過程B運行時間大約爲45分鐘。雖然進程B正在運行,但進程A出現很多死鎖警告,我想擺脫這些。TransactionScope優先級(擺脫死鎖情況)

簡單的選項是「當進程B運行時不要運行進程A」,但必須有更好的方法。我在兩個進程中都使用EntityFramework 6和TransactionScope。我沒有找到如何設置優先級或類似的東西在我的進程。這可能嗎?

編輯: 我忘了說,我已經在使用每一個記錄刪除事務,所有記錄不是一個事務。在內部循環中,我創建了新的DBContext和TransactionScope,因此每個記錄都有自己的事務。我的問題是刪除記錄仍然需要一些時間,因爲相關的BLOB和其他相關表中的數據(可以說每行約5秒)。當刪除過程(B)與插入過程(A)交叉時,我仍然遇到死鎖情況。

+0

如果他們都有一定的時間,你能對齊他們嗎?如果A需要1分鐘才能完成,並且從20:00開始,那麼你可以在20:03開始B? – Kuzgun

+1

B在一次交易中沒有理由需要45分鐘。刪除可以在少於30秒的交易中以較小尺寸的循環完成。解決超時問題。 – TomTom

回答

5

交易沒有優先權。死鎖受害者是由數據庫選擇的,最常用的是「需要回滾的工作」。避免死鎖的一種方法是確保您阻止而不是死鎖,通過以相同順序訪問表並鎖定最終級別(例如,在讀取數據時採取UPDLOCK,以避免兩個查詢被讀取鎖,然後試圖升級到寫鎖)。但最終,這是一個棘手的領域 - 需要花費45M才能完成(請告訴我這不是一次交易!)總是會引發問題。

+0

我編輯了我的帖子,是的它不是一個單一的交易。我發現如何通過TSQL設置死鎖優先級,但當然這有助於設置哪個進程會失敗。 Mabye當B準備好運行時,我應該首先考慮A的開始。 – AlmightyMato

1

返工過程B不會一次全部刪除,而是以更小的批次從未超過1分鐘。在循環中運行這些操作,直到完成所有要刪除的操作。

+0

我編輯了我的帖子。我已經在使用每行一個事務,而不是一個事務。 – AlmightyMato

+0

一行30秒?這是瘋狂的,即使是10 x2gb blob(這將在交易之外回收)。我會開始調試。你的服務器有多重載?什麼是規格?請提醒您...我在這裏看到一個嚴重的問題。一行cascaging到100個100 x 100mb的其他行應該在不到5秒的時間內刪除。 – TomTom

+0

我不是這方面的專家,它只是一個建議值,所以可以說它像你說的那樣運行2-5秒。似乎還有足夠的時間與另一個(插入)事務發生衝突,因爲兩者都試圖同時編輯表。 – AlmightyMato