我們試圖做一些完整性檢查我們的數據庫狀態用於診斷的原因,所以我們包裹我們加上跑診斷第二查詢一個TransactionScope修改ORM查詢 - 是這樣的:的TransactionScope包裝ORM電話,TransactionStateAborted.CreateAbortingClone異常的第二個呼叫
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, _maxTimeout))
{
ORM.DeleteItem();
ORM.CheckIntegrity();
scope.Complete();
}
這是一個手卷ORM,和這兩個電話最終做他們的位嵌套事務將範圍縮小在底部。換句話說,當你往下挖,DeleteItem()使用(TransactionScope的newscope的=新的TransactionScope(TransactionScopeOptions.Required,_maxTimeout) {...}
和CheckIntegrity()也有同樣有 。
對於大多數情況,它一直工作正常,但我遇到了一個奇怪的情況。當有人對查詢輸入一些錯誤的輸入時,DeleteItem()調用可能會拋出異常。該異常完全被捕獲並在棧級別的包裝。我相信例外,也會引發以前它獲取嵌套TransactionScope的下方。
但是,當我們在CheckIntegrity()調用中涉及嵌套的作用域創建時,它會從CreateAbortingClone構造函數中引發「Transaction was aborted error」事務。內部異常爲空。
大多數CreateAbortingClone互動的每一個其他提及與DTC促銷(或失敗物)和內部異常做反映。
我推斷CheckIntegrity()調用中的異常異常是由於DeleteItem()引發了異常 - 即使它被吞下了。
A)是一個正確的推理? TransactionScope是否對所有拋出,處理或不處理的異常敏感?
B)有沒有什麼辦法來檢測使CheckIntegrity()調用之前?我的意思是重新做我們的ORM讓異常滲透或添加其他全局標誌?
感謝 馬克
周圍多一點在調試器戳,我發現TransactionScope.expectedCurrent .InternalTransaction.State是DeleteItem()調用後的TransactionStateAborted,支持我的推理。問題是所有這些成員是私人的... – user1664043
發現msdn文檔說:「如果在TransactionScope內發生異常,事務被標記爲不一致並被放棄。」但是在這兩行之間還有很多沒有用到的地方 - 比如,如果異常處理的是低於範圍的幾個調用級別,那麼它就不會出現問題,並且它可以防止任何新的範圍在之後被嵌套。 – user1664043
注意瓶子裏的時間 - 最終我發現了System.Transactions.Transaction.Current.TransactionInformation.Status,並認爲它可以用來判斷是否有任何異常(已處理或未處理)破壞了包裝事務。如果它是TransactionStatus.Aborted,那麼你已經洗腦了。我還想到,您可以在外層使用包裝事務來檢測何時拋出異常。在你外面的呼叫中,你並不希望連續的數據庫調用進入不同的層。當然,設計你的代碼不要吞噬重大事件會更好。 – user1664043