Udostępnij za pośrednictwem


Zarządzanie współbieżnością za pomocą DependentTransaction

Transaction Obiekt zostanie utworzony przy użyciu DependentClone metody. Jego jedynym celem jest zagwarantowanie, że transakcja nie może zatwierdzić, podczas gdy niektóre inne fragmenty kodu (na przykład wątek procesu roboczego) nadal wykonują pracę nad transakcją. Gdy praca wykonywana w ramach sklonowanej transakcji zostanie ukończona i gotowa do zatwierdzenia, może powiadomić twórcę transakcji przy użyciu Complete metody . W związku z tym można zachować spójności i poprawności danych.

DependentTransaction Klasy można również zarządzać współbieżności między zadania asynchronicznego. W tym scenariuszu nadrzędnego można kontynuować wykonywania żadnych kodu podczas klon zależny działa na własnych zadań. Innymi słowy wykonanie elementu nadrzędnego nie jest blokowane do momentu ukończenia zależności.

Tworzenie klon zależny

Aby utworzyć zależne transakcji, należy wywołać DependentClone metody i przekazać DependentCloneOption wyliczenia jako parametr. Ten parametr określa zachowanie transakcji, jeśli Commit jest wywoływana w transakcji nadrzędnej przed klon zależny wskazuje, że jest gotowa na zatwierdzenie transakcji (przez wywołanie metody Complete metody). Następujące wartości są prawidłowe dla tego parametru:

  • BlockCommitUntilComplete Tworzy transakcję zależną, która blokuje proces zatwierdzania transakcji nadrzędnej do czasu limitu czasu transakcji nadrzędnej lub do momentu Complete wywołania wszystkich zależności wskazujących ich ukończenie. Jest to przydatne, gdy klient nie chce, aby transakcja nadrzędna została zatwierdzona do momentu zakończenia transakcji zależnych. Jeśli element nadrzędny zakończy pracę starszych niż zależne transakcji i wywołuje Commit dla transakcji, proces zatwierdzania jest zablokowany w stanie, w którym dodatkowe pracy można wykonać na transakcji i można było utworzyć nowe rejestracji, aż wszystkie wywołania zależności Complete. Jako ukończony je wszystkie jego pracę, a następnie wywołać Complete, rozpocznie się proces zatwierdzania dla transakcji.

  • RollbackIfNotCompleteZ drugiej strony tworzy transakcję zależną, która automatycznie przerywa, jeśli Commit jest wywoływana na transakcji nadrzędnej przed Complete wywołania. W takim przypadku wszystkie prace wykonane w transakcji zależne jest prawidłowa w ramach jednej transakcji okres istnienia i nie jest Państwo przekazać tylko jego części.

Complete Metoda musi być wywoływana tylko raz, gdy aplikacja zakończy pracę nad zależną transakcją. W przeciwnym razie InvalidOperationException jest zgłaszana wartość . Po wywołaniu to wywołanie, nie należy spróbować żadnych dodatkowych działań w transakcji lub wyjątku.

Poniższy przykład kodu pokazuje, jak utworzyć transakcję zależną w celu zarządzania dwoma współbieżnymi zadaniami przez sklonowanie zależnej transakcji i przekazanie jej do wątku roboczego.

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();  
}  

Kod klienta tworzy zakres transakcji, który ustawia również otoczenia transakcji. Transakcja otoczenia nie mają być przekazywane do wątku roboczego. Zamiast tego należy sklonować bieżącej transakcji (otoczenia) przez wywołanie metody DependentClone metody w bieżącej transakcji i przekazać zależne od do wątku roboczego.

ThreadMethod Metoda wykonuje na nowy wątek. Klient uruchamia nowy wątek, przekazywania zależne transakcji jako ThreadMethod parametru.

Ponieważ zależne transakcji jest tworzone z BlockCommitUntilComplete, ma gwarancji, że nie można zatwierdzić transakcji, aż wszystkie transakcyjnych zadań wykonywanych na sekundę wątek został zakończony i Complete jest wywoływana w transakcji zależnych. Oznacza to, że jeśli zakres klienta kończy się (gdy próbuje usunąć obiekt transakcji na końcu using instrukcji), zanim nowy wątek wywołuje Complete transakcję zależną, kod klienta blokuje się do Complete momentu wywołania zależnego obiektu. Następnie transakcji może zakończyć przekazywanie lub przerywanie.

Problemy z współbieżności

Istnieje kilka problemów współbieżności dodatkowe, które należy zwrócić uwagę podczas korzystania z DependentTransaction klasy:

  • Jeśli wątku roboczego powoduje wycofanie transakcji, ale nadrzędnego próbuje zatwierdzić, TransactionAbortedException zgłaszany.

  • Należy utworzyć nowy klon zależny dla każdego wątku roboczego w transakcji. Nie przekazuj tego samego klonu zależnego do wielu wątków, ponieważ tylko jeden z nich może go wywołać Complete .

  • Jeśli wątku roboczego spawns nowego wątku roboczego, upewnij się, że tworzenie klon zależny od klon zależny i przekazywanie ich do nowego wątku.

Zobacz też