共用方式為


使用 DependentTransaction 管理並行存取

Transaction 物件係使用 DependentClone 方法建立。 其唯一目的在於保證當其他程式碼片段 (例如,背景工作執行緒仍在執行交易工作時,不會認可交易。 當完成並準備好認可在複製之交易中所執行的工作時,可以使用 Complete 方法來通知交易的建立者。 這麼一來,您便可保持資料的一致性和正確性。

您也可以使用 DependentTransaction 類別來管理非同步工作之間的並行存取。 在此情況下,當相依的複製工作在執行自己的工作時,父項仍舊可以繼續執行任何程式碼。 換句話說,不管相依項是否完成工作,都不會影響父項執行工作。

建立相依的複製品

若要建立相依的交易,請呼叫 DependentClone 方法,並將 DependentCloneOption 列舉型別當成參數傳送出去。 在相依的複製品表示它以準備好認可交易 (藉由呼叫 Commit 方法) 之前,如果在父交易呼叫 Complete 的話,此參數將會定義交易行為。 下列各值為此參數可用的有效值:

  • BlockCommitUntilComplete 會建立相依交易,此交易會封鎖父交易的認可程序,直到父交易逾時,或直到對所有相依交易呼叫 Complete,表示這些相依交易完成。 當用戶端不想在完成相依交易之前即認可父交易時,這個參數就會非常有用。 如果父項比相依交易早一步完成工作,並在交易上呼叫 Commit,則會將認可處理序封鎖在某個狀態下。在此狀態下,您仍可以在交易上執行其他工作,並建立新的登記,直到所有相依項都呼叫 Complete 為止。 一旦全部都完成各自的工作並呼叫 Complete,就會馬上開始交易的認可處理序。

  • 另一方面,如果在呼叫 RollbackIfNotComplete 之前,先在父交易上呼叫了 Commit,則 Complete 會建立能自動中止的相依交易。 在此情況下,所有在相依交易中完成的工作會保留一段交易存留期不變,而且沒人有機會認可其中一部分。

當您的應用程式完成了在相依交易上的工作,必須呼叫 Complete 方法一次 (而且只能一次);否則,會擲回 InvalidOperationException。 在叫用這個呼叫後,您不應嘗試在交易上執行任何額外的工作,否則會擲回例外狀況。

下列程式碼範例說明如何藉由複製相依的交易並將其傳遞至背景工作執行緒,來建立相依交易以管理兩個並行的工作。

public class WorkerThread  
{  
    public void DoWork(DependentTransaction dependentTransaction)  
    {  
        Thread thread = new Thread(ThreadMethod);  
        thread.Start(dependentTransaction);
    }  
  
    public void ThreadMethod(object transaction)
    {
        DependentTransaction dependentTransaction = transaction as DependentTransaction;  
        Debug.Assert(dependentTransaction != null);
        try  
        {  
            using(TransactionScope ts = new TransactionScope(dependentTransaction))  
            {  
                /* Perform transactional work here */
                ts.Complete();  
            }  
        }  
        finally  
        {  
            dependentTransaction.Complete();
             dependentTransaction.Dispose();
        }  
    }  
  
//Client code
using(TransactionScope scope = new TransactionScope())  
{  
    Transaction currentTransaction = Transaction.Current;  
    DependentTransaction dependentTransaction;
    dependentTransaction = currentTransaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete);  
    WorkerThread workerThread = new WorkerThread();  
    workerThread.DoWork(dependentTransaction);  
    /* Do some transactional work here, then: */  
    scope.Complete();  
}  

用戶端程式碼可建立同時能設定環境交易的交易範圍。 您不應該將環境交易傳遞至背景工作執行緒。 反之,您應該呼叫目前交易上的 DependentClone 方法來複製目前 (環境) 交易,並將相依交易傳遞給背景工作執行緒。

ThreadMethod 方法會在新執行緒上執行。 用戶端開始新的執行緒後,會將相依交易當成 ThreadMethod 參數傳送出去。

由於相依交易係由 BlockCommitUntilComplete 所建立,因此可以保證直到第二個執行緒上所有執行的交易工作都已完成,並且在相依交易上呼叫 Complete 後,才會認可交易。 這表示,在新執行緒於相依交易上呼叫 Complete 之前,如果用戶端的範圍結束 (這時該用戶端嘗試在 using 陳述式結束階段處置交易物件),則用戶端程式碼會在對相依交易呼叫 Complete 之前保持封鎖。 接著,交易便可完成認可或中止。

並行問題

使用 DependentTransaction 類別時,您需要注意下列幾項額外的並行問題:

  • 如果背景工作執行緒復原了交易,但是父交易卻嘗試認可它,則會擲回 TransactionAbortedException

  • 您應該為交易中的每個背景工作執行緒建立新的相依複製品。 請勿將同樣的相依複製品傳遞給多個執行緒,因為其中只有一個執行緒可以在相依交易上呼叫 Complete

  • 如果背景工作執行緒繁衍出新的背景工作執行緒,請記得從相依複製品中建立一個相依複製品,並將其傳遞給背景工作執行緒。

另請參閱