Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Objekt Transaction je vytvořen pomocí DependentClone metody. Jediným účelem je zajistit, že transakce se nemůže uzavřít, dokud některé jiné části kódu (například pracovní vlákno) stále vykonávají práci na transakci. Po dokončení práce v rámci klonované transakce a když je připravena k potvrzení, může informovat tvůrce transakce pomocí metody Complete. Můžete tak zachovat konzistenci a správnost dat.
Třídu DependentTransaction lze také použít ke správě souběžnosti mezi asynchronními úlohami. V tomto scénáři může nadřazený pokračovat v provádění jakéhokoli kódu, zatímco klon zpracovává své vlastní úkoly. Jinými slovy, spuštění nadřazeného procesu není blokováno až do dokončení závislého procesu.
Vytvoření závislého klonu
Chcete-li vytvořit závislé transakce, zavolejte metodu DependentClone a předejte DependentCloneOption výčet jako parametr. Tento parametr definuje chování transakce, pokud je Commit volána na nadřazené transakci předtím, než závislý klon indikuje, že je transakce připravena k potvrzení (voláním metody Complete). Pro tento parametr jsou platné následující hodnoty:
BlockCommitUntilComplete vytvoří závislou transakci, která blokuje proces potvrzování nadřazené transakce, dokud nevyprší časový limit nadřazené transakce, nebo dokud Complete není volána na všechny závislé, čímž se označí jejich dokončení. To je užitečné, když klient nechce nadřazenou transakci potvrdit, dokud nejsou závislé transakce dokončeny. Pokud nadřazený proces dokončí svou práci dříve než závislé transakce a zavolá Commit na transakci, je proces potvrzení blokován do stavu, ve kterém lze na transakci provést další práce a mohou být vytvořena nová zařazení, dokud všechny závislé nezavolají Complete. Jakmile všichni z nich dokončí svou práci a volání Complete, zahájí se proces potvrzení transakce.
RollbackIfNotComplete, na druhé straně, vytvoří závislou transakci, která se automaticky zruší, pokud je Commit volána na nadřazené transakci před tím, než je Complete zavolána. V tomto případě je veškerá práce provedená v závislé transakci nedotčena v rámci životnosti jedné transakce a nikdo nemá šanci potvrdit pouze část této práce.
Metoda Complete musí být volána pouze jednou, když vaše aplikace dokončí svou práci na závislé transakci; v opačném případě InvalidOperationException je vyvolána. Po vyvolání tohoto volání se nesmíte pokusit o žádnou další práci na transakci nebo je vyvolána výjimka.
Následující příklad kódu ukazuje, jak vytvořit závislá transakce pro správu dvou souběžných úloh klonováním závislé transakce a předáním do pracovního vlákna.
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();
}
Klientský kód vytvoří transakční rozsah, který také nastaví ambientní transakci. Nesmíte předat ambientní transakci do pracovního vlákna. Místo toho byste měli naklonovat aktuální (okolí) transakce voláním DependentClone metody na aktuální transakci a předat závislé na pracovní vlákno.
Metoda ThreadMethod se spustí v novém vlákně. Klient spustí nové vlákno, přičemž jako parametr předává závislou transakci ThreadMethod.
Vzhledem k tomu, že závislá transakce je vytvořena s BlockCommitUntilComplete, je zaručeno, že transakce nemůže být potvrzena, dokud nejsou všechny transakční práce provedené na druhém vlákně dokončeny a Complete je vyvolán na závislé transakci. To znamená, že pokud obor klienta končí (když se pokusí likvidovat objekt transakce na konci using příkazu) před tím, než nové vlákno zavolá Complete na závislou transakci, klientský kód blokuje, dokud nové vlákno nezavolá Complete na závislou. Transakce pak může dokončit buď potvrzení (commitování), nebo přerušení (abortování).
Problémy se souběžností
Při používání DependentTransaction třídy je potřeba vědět o několika dalších problémech souběžnosti:
Pokud pracovní vlákno vrátí zpět transakci, ale nadřazený se pokusí ji potvrdit, je vyhozena TransactionAbortedException.
Pro každé pracovní vlákno v transakci byste měli vytvořit nový závislý klon. Nepředávejte stejný závislý klon více vláken, protože na ně může volat Complete pouze jeden z nich.
Pokud pracovní vlákno vytvoří nové pracovní vlákno, nezapomeňte vytvořit závislý klon ze závislého klonu a předat ho do nového vlákna.