Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
Objektet Transaction skapas med hjälp av DependentClone metoden . Det enda syftet är att garantera att transaktionen inte kan genomföras medan vissa andra kodstycken (till exempel en arbetstråd) fortfarande utför arbete med transaktionen. När arbetet som utförs inom den klonade transaktionen är klart och redo att genomföras kan det meddela den som skapat transaktionen med hjälp av Complete-metoden. Därför kan du bevara datas konsekvens och korrekthet.
Klassen DependentTransaction kan också användas för att hantera samtidighet mellan asynkrona uppgifter. I det här scenariot kan föräldern fortsätta att köra valfri kod medan den beroende klonen arbetar på sina egna uppgifter. Med andra ord blockeras inte förälderkörningen förrän den beroende har slutförts.
Skapa en beroende klon
Om du vill skapa en beroende transaktion anropar du DependentClone metoden och skickar DependentCloneOption uppräkningen som en parameter. Den här parametern definierar beteendet för transaktionen om Commit anropas på den överordnade transaktionen innan den beroende klonen anger att den är redo för transaktionen att avslutas (genom att anropa Complete-metoden). Följande värden är giltiga för den här parametern:
BlockCommitUntilComplete skapar en beroende transaktion som blockerar åtagandeprocessen för den överordnade transaktionen tills den överordnade transaktionen överskrider tidsgränsen, eller tills Complete anropas på alla beroenden och anger att de har slutförts. Detta är användbart när klienten inte vill att huvudtransaktionen ska bekräftas förrän de beroende transaktionerna har slutförts. Om det överordnade avslutar sitt arbete tidigare än den beroende transaktionen och anropar Commit, blockeras incheckningsprocessen i ett tillstånd där ytterligare arbete kan utföras på transaktionen och nya registreringar kan skapas, tills alla beroenden anropar Complete. Så snart alla har slutfört sitt arbete och anropat Complete börjar överföringsprocessen för transaktionen.
RollbackIfNotComplete, å andra sidan, skapar en beroende transaktion som automatiskt avbryter om Commit anropas på den överordnade transaktionen innan Complete anropas. I det här fallet är allt arbete som utförs i den beroende transaktionen intakt inom en transaktionens livstid, och ingen har en chans att begå endast en del av arbetet.
Metoden Complete får bara anropas en gång när programmet har slutfört sitt arbete med den beroende transaktionen. Annars genereras en InvalidOperationException . När det här anropet har anropats får du inte försöka utföra något ytterligare arbete med transaktionen, eller så utlöses ett undantag.
I följande kodexempel visas hur du skapar en beroende transaktion för att hantera två samtidiga uppgifter genom att klona en beroende transaktion och skicka den till en arbetstråd.
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();
}
Klientkoden skapar ett transaktionsomfång som också anger den omgivande transaktionen. Du bör inte skicka den omgivande transaktionen till arbetstråden. I stället bör du klona den aktuella (omgivande) transaktionen genom att anropa DependentClone-metoden för den aktuella transaktionen och skicka den beroende transaktionen till arbetstråden.
Metoden ThreadMethod körs på den nya tråden. Klienten startar en ny tråd och skickar den beroende transaktionen som ThreadMethod parameter.
Eftersom den beroende transaktionen skapas med BlockCommitUntilCompletegaranteras att transaktionen inte kan genomföras förrän allt transaktionsarbete som utförs på den andra tråden har slutförts och Complete anropas för den beroende transaktionen. Det innebär att om klientens räckvidd upphör (när den försöker bortse från transaktionsobjektet vid slutet av using-satsen) innan den nya tråden anropar Complete på den beroende transaktionen, blockeras klientkoden tills Complete anropas på den beroende. Sedan kan transaktionen fullföljas eller avbrytas.
Samtidighetsproblem
Det finns några ytterligare samtidighetsproblem som du måste känna till när du använder DependentTransaction klassen:
Om arbetstråden rullar tillbaka transaktionen men den överordnade försöker begå den, kastas en TransactionAbortedException.
Du bör skapa en ny beroende klon för varje arbetstråd i transaktionen. Skicka inte samma beroende klon till flera trådar, eftersom endast en av dem kan anropa Complete på den.
Om arbetstråden skapar en ny arbetstråd ska du skapa en beroende klon från den beroende klonen och skicka den till den nya tråden.