70-503: Transaction Basics

Ten artykuł pochodzi z serii przygotowań do egzaminu 70-503: Windows Communication Foundation.

Podstawową funkcją transakcji jest zagwarantowanie zasad ACID:

  • atomowości (ang. atomicity),
  • spójności (ang. consistency),
  • izolacji (ang. isolation),
  • trwałości (ang. durability).

Kiedy operacje związane z bazą odbywają się na wielu maszynach i wielu zbiorach danych, nie jest to takie proste. WCF wspomaga programistę w tym zadaniu.

W celu spełnienia zasad ACID najczęstszym podejściem jest wykorzystanie dwuetapowego zgłoszenia (ang. two-phase commit):

  1. Etap przygotowania (ang. prepare phase) – koordynator transakcji zarządza tym etapem, wysyła żądanie przygotowania do wszystkich zarządców transakcji (ang. transaction manager), na maszynach biorących udział w procesie. Zarządcy odsyłają informację o tym, czy operacje zakończyły się sukcesem, czy porażką. Kiedy wszyscy odpowiedzą etap przygotowania uznajemy za zakończony.
  2. Etap zgłoszenia (ang. commit phase) – zależny od wyników etapu poprzedniego; jeżeli tamten zakończy się sukcesem – wysyłane zostaje żądanie Commit, w przeciwnym wypadku, jeżeli chociaż jedna maszyna zwróci komunikat błędu – koordynator transakcji wysyła żądanie Abort, aby poinformować zarządców o potrzebie cofnięcia zmian.

W zależności od sytuacji wykorzystany może zostać jeden z trzech zarządców transakcji:

  • The Lightweight Transaction Manager (LTM) – wprowadzony w .NET 2.0 przez przestrzeń nazw System.Transaction (do projektu trzeba dodać assembly); poniższy przykład aktualizuje bazę danych w ramach lekkiej transakcji. W celu zgłoszenia transakcji wywołana jest metoda Complete:
  •    1: using (TransactionScope ts = new TransactionScope())
       2: {
       3:   using (SqlConnection cn1 = new SqlConnection(connectionString))
       4:   {
       5:     insertRecord(cn1, "User1");
       6:     using(SqlConnection cn2 = new SqlConnection(connectionString))
       7:     {
       8:       insertRecord(cn2, "User2");
       9:     }
      10:   }
      11:   ts.Complete();
      12: }
      13: private void insertRecord(SqlConnection cn, string userName)
      14: {
      15:   SqlCommand cmd = new SqlCommand(String.Format("Insert INTO [Users]" +" VALUES('{0}')", userName), cn);
      16:   cn.Open();
      17:   cmd.ExecuteNonQuery();
      18: }
  • OLE Transactions (OleTx),
  • WS-Atomic Transactions (WS-AT).

Transakcji możemy pozwolić na działanie poza granicami serwisu, lub nie. Decyzję o tym podejmują klient i serwis, jednak jeżeli serwis wymaga transakcji, blokowanie po stronie klienta spowoduje błąd aplikacji. Ustawione może to zostać w bindingu za pomocą atrybutu TransactionFlow, zarówno imperatywnie jak i deklaratywnie:

   1: // C#
   2: WSHttpBinding binding = new WSHttpBinding();
   3: binding.TransactionFlow = true;
   4:  
   5: <!--XML-->
   6: <bindings>
   7: <wsHttpBinding>
   8: <binding name="Transactional" transactionFlow="true" />
   9: </wsHttpBinding>
  10: </bindings>

 

 

Dodatkowo wymagane jest, aby operacje serwisu były oznaczone atrybutem TransactionFlow, który wskazuje na to, że mogą one brać udział w transakcji:

   1: [ServiceContract]
   2: public interface IDemoContract
   3: {
   4:   [OperationContract]
   5:   [TransactionFlow(TransactionFlowOption.Allowed)]
   6:   void TransactedMethod(...);
   7: }

Po stronie klienta w ten sam sposób zostanie udekorowana klasa proxy:

   1: public class DemoService : IDemoContract
   2: {
   3:   [TransactionFlow(TransactionFlowOption.Allowed)]
   4:   public void TransactedMethod(...)
   5:   {...}
   6: }

W powyższym przykładzie TransactionFlow ustawiony jest na wartość TransactionFlowOption.Allowed, która pozwala transakcji klienta przechodzić do serwisu. Domyślna opcja TransactionFlowOption.NotAllowed sprawia, że żadna transakcja nie jest przesyłana.

Uwaga: Transakcje nie działają w przypadku metod typu one-way – bez komunikatu zwrotnego nie ma możliwości stworzenia rozproszonej transakcji.

Tagi: , , , ,

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading


Eastgroup.pl na facebooku