2016-05-24 28 views
0

我有一個UnitOfWork類,根據塊中的錯誤提交或回滾事務。Dispose處理異常()

try 
{ 
    using (var uow = new UnitOfWork()) 
    { 
     // Do something here that causes an exception 
    } 
} 
catch 
{ 
    using (var uow = new UnitOfWork()) 
    { 
     // Log exception 
    } 
} 

我已經通過這篇文章了:

class UnitOfWork: IDispose 
{ 
     public void Dispose() 
     { 
       if (Marshal.GetExceptionCode() == 0 
        || Marshal.GetExceptionPointers() == IntPtr.Zero) 
       { 
         // Commit 
       } 
       else 
       { 
         // Rollback 
       } 
      } 
     } 
} 

這個類以下列方式使用 Detecting a Dispose() from an exception inside using block

在上面的問題,史蒂芬(誰回答的人之一)提到如果我在Dispose()中爲「try」部分的「using」塊檢測到一個異常,我不能在「catch」塊中創建另一個UnitOfWork類並將錯誤記錄到數據庫(因爲「Marshal」代碼在Dispose()中將繼續說有一個例外),這意味着ExceptionCode和ExceptionPointers將從try塊到catch塊「浮動」(?)。

但是,在我的情況下,這工作正常 - 即。如果在「try」部分的「using(var uow = new UOW)」塊中存在異常,它會正確捕獲該異常,然後在catch塊中傳遞「if」條件,導致發生提交併允許我記錄異常。

歸結起來,我對Marshal.GetExceptionPointers()的工作方式有不完全的理解。有人可以確認我的使用模式是否可以正常工作(到目前爲止所有的測試都顯示它可以正常工作),以及Marshal.GetExceptionPointers()在做什麼?

回答

1

IDisposable.Dispose旨在釋放資源,提交/回滾操作是一個壞主意。調用者應該知道如何處理異常以及如何回滾。

using (var unitOfWork = new UnitOfWork()) 
{ 
    try 
    { 
     Prepare(); 
     Step1(); 
     Step2(); 
     unitOfWork.Commit(); 
    } 
    catch(PrepareException e) 
    { 
     //no necessary to rollback, just log it 
    } 
    catch(FirstStepException e1) 
    { 
     //rollback step1 
    } 
    catch(SecondStepException e2) 
    { 
     //rollback step1 and step2 
    } 
} 
+0

,而把犯處置肯定是壞主意,將回滾沒有,而實際上在很多地方,包括標準DbTransaction,TransactionScope的等 – Evk

+1

@Evk問題做有時是沒有全球性的解決方案回滾。只有調用者知道所做的事情以及需要回滾的內容。看我的編輯。 –

+0

但你還有什麼其他選擇(如果我們談論抽象事務和它的Dispose方法)?您不能保留在Transaction.Dispose中應用的部分更改,無論如何您必須提交或回滾。 – Evk