Sdílet prostřednictvím


Tok transakcí WS

Ukázka TransactionFlow ukazuje použití transakce koordinované klientem a možnosti klienta a serveru pro tok transakcí pomocí protokolu WS-Atomic Transaction nebo OleTransactions. Tento příklad je založen na Začínáme, který implementuje službu kalkulačky, ale operace jsou navrženy tak, aby ukázaly využití TransactionFlowAttribute ve spojení s výčtem TransactionFlowOption k určení, do jaké míry je povolen tok transakce. V rámci toku transakce se protokol požadovaných operací zapíše do databáze a trvá až do dokončení koordinované transakce klienta – pokud se transakce klienta nedokončí, transakce webové služby zajistí, že příslušné aktualizace databáze nebudou potvrzeny.

Poznámka

Postup nastavení a pokyny k sestavení pro tuto ukázku najdete na konci tohoto tématu.

Po zahájení připojení ke službě a transakci klient přistupuje k několika operacím služby. Smlouva pro službu je definována následujícím způsobem, přičemž každá operace demonstruje jiné nastavení pro TransactionFlowOption.

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
    [OperationContract]
    [TransactionFlow(TransactionFlowOption.Mandatory)]
    double Add(double n1, double n2);
    [OperationContract]
    [TransactionFlow(TransactionFlowOption.Allowed)]
    double Subtract(double n1, double n2);
    [OperationContract]
    [TransactionFlow(TransactionFlowOption.NotAllowed)]
    double Multiply(double n1, double n2);
    [OperationContract]
    double Divide(double n1, double n2);
}

Tím se definují operace v pořadí, v jakém se mají zpracovat:

  • Požadavek na operaci Add musí obsahovat provedenou transakci.

  • Požadavek na operaci Subtract může zahrnovat probíhající transakci.

  • Požadavek na operaci Multiply nesmí zahrnovat tok transakce prostřednictvím explicitního nastavení NotAllowed.

  • Požadavek na operaci Divide nesmí zahrnovat tok transakce prostřednictvím vynechání atributu TransactionFlow.

Chcete-li povolit tok transakce, musí být použity vazby s vlastností <transactionFlow>, kromě příslušných atributů operace. V této ukázce konfigurace služby zveřejňuje koncový bod TCP, koncový bod HTTP a jeden metadatový bod Exchange. Koncový bod TCP a koncový bod HTTP používají následující vazby, z nichž obě mají povolenou vlastnost <transactionFlow>.

<bindings>
  <netTcpBinding>
    <binding name="transactionalOleTransactionsTcpBinding"
             transactionFlow="true"
             transactionProtocol="OleTransactions"/>
  </netTcpBinding>
  <wsHttpBinding>
    <binding name="transactionalWsatHttpBinding"
             transactionFlow="true" />
  </wsHttpBinding>
</bindings>

Poznámka

Systémem poskytovaný netTcpBinding umožňuje specifikaci transactionProtocol, zatímco systémem poskytovaný wsHttpBinding používá pouze interoperabilnější protokol WSAtomicTransactionOctober2004. Protokol OleTransactions je k dispozici pouze pro použití klienty Windows Communication Foundation (WCF).

Pro třídu, která implementuje rozhraní ICalculator, mají všechny metody vlastnost TransactionScopeRequired nastavenu na true. Toto nastavení deklaruje, že všechny akce prováděné v rámci metody probíhají v rozsahu transakce. V tomto případě mezi provedené akce patří záznam do databáze protokolů. Pokud požadavek operace zahrnuje tok transakce, akce probíhají v rámci rozsahu příchozí transakce nebo se automaticky vygeneruje nový obor transakce.

Poznámka

Vlastnost TransactionScopeRequired definuje chování místního pro implementace metody služby a nedefinuje schopnost klienta ani požadavek na tok transakce.

// Service class that implements the service contract.
[ServiceBehavior(TransactionIsolationLevel = System.Transactions.IsolationLevel.Serializable)]
public class CalculatorService : ICalculator
{
    [OperationBehavior(TransactionScopeRequired = true)]
    public double Add(double n1, double n2)
    {
        RecordToLog(String.Format(CultureInfo.CurrentCulture, "Adding {0} to {1}", n1, n2));
        return n1 + n2;
    }

    [OperationBehavior(TransactionScopeRequired = true)]
    public double Subtract(double n1, double n2)
    {
        RecordToLog(String.Format(CultureInfo.CurrentCulture, "Subtracting {0} from {1}", n2, n1));
        return n1 - n2;
    }

    [OperationBehavior(TransactionScopeRequired = true)]
    public double Multiply(double n1, double n2)
    {
        RecordToLog(String.Format(CultureInfo.CurrentCulture, "Multiplying {0} by {1}", n1, n2));
        return n1 * n2;
    }

    [OperationBehavior(TransactionScopeRequired = true)]
    public double Divide(double n1, double n2)
    {
        RecordToLog(String.Format(CultureInfo.CurrentCulture, "Dividing {0} by {1}", n1, n2));
        return n1 / n2;
    }

    // Logging method omitted for brevity
}

Nastavení služby TransactionFlowOption na operacích se u klienta projeví v definici rozhraní ICalculator, kterou generuje klient. Nastavení vlastnosti transactionFlow služby se také projeví v konfiguraci aplikace klienta. Klient může vybrat přenos a protokol výběrem příslušného endpointConfigurationName.

// Create a client using either wsat or oletx endpoint configurations
CalculatorClient client = new CalculatorClient("WSAtomicTransaction_endpoint");
// CalculatorClient client = new CalculatorClient("OleTransactions_endpoint");

Poznámka

Pozorované chování tohoto vzorku je stejné bez ohledu na to, který protokol nebo přenos je zvolen.

Po navázání připojení ke službě vytvoří klient nové TransactionScope pro volání operací služby.

// Start a transaction scope
using (TransactionScope tx =
            new TransactionScope(TransactionScopeOption.RequiresNew))
{
    Console.WriteLine("Starting transaction");

    // Call the Add service operation
    //  - generatedClient will flow the required active transaction
    double value1 = 100.00D;
    double value2 = 15.99D;
    double result = client.Add(value1, value2);
    Console.WriteLine("  Add({0},{1}) = {2}", value1, value2, result);

    // Call the Subtract service operation
    //  - generatedClient will flow the allowed active transaction
    value1 = 145.00D;
    value2 = 76.54D;
    result = client.Subtract(value1, value2);
    Console.WriteLine("  Subtract({0},{1}) = {2}", value1, value2, result);

    // Start a transaction scope that suppresses the current transaction
    using (TransactionScope txSuppress =
                new TransactionScope(TransactionScopeOption.Suppress))
    {
        // Call the Subtract service operation
        //  - the active transaction is suppressed from the generatedClient
        //    and no transaction will flow
        value1 = 21.05D;
        value2 = 42.16D;
        result = client.Subtract(value1, value2);
        Console.WriteLine("  Subtract({0},{1}) = {2}", value1, value2, result);

        // Complete the suppressed scope
        txSuppress.Complete();
    }

    // Call the Multiply service operation
    // - generatedClient will not flow the active transaction
    value1 = 9.00D;
    value2 = 81.25D;
    result = client.Multiply(value1, value2);
    Console.WriteLine("  Multiply({0},{1}) = {2}", value1, value2, result);

    // Call the Divide service operation.
    // - generatedClient will not flow the active transaction
    value1 = 22.00D;
    value2 = 7.00D;
    result = client.Divide(value1, value2);
    Console.WriteLine("  Divide({0},{1}) = {2}", value1, value2, result);

    // Complete the transaction scope
    Console.WriteLine("  Completing transaction");
    tx.Complete();
}

Console.WriteLine("Transaction committed");

Volání na operace jsou následující:

  • Požadavek Add přenáší požadovanou transakci do služby a akce služby probíhají v rámci transakce klienta.

  • První Subtract požadavek také přenáší povolenou transakci ke službě a znovu dochází k angažování služby v rámci rozsahu transakce klienta.

  • Druhý Subtract požadavek se provádí v rámci nového oboru transakce deklarovaného s možností TransactionScopeOption.Suppress. Tím se potlačí počáteční vnější transakce klienta a požadavek neprovádí transakci do služby. Tento přístup umožňuje klientovi explicitně vyjádřit výslovný nesouhlas a chránit před tokem transakce do služby, pokud to není nutné. Akce služby probíhají v rámci nové a nepřipojené transakce.

  • Požadavek Multiply neprovádí transakci do služby, protože vygenerovaná definice rozhraní ICalculator klienta zahrnuje TransactionFlowAttribute nastavenou na TransactionFlowOptionNotAllowed.

  • Požadavek Divide neprovádí transakci do služby, protože znovu vygenerovaná definice rozhraní ICalculator klienta neobsahuje TransactionFlowAttribute. Akce služby se znovu provádějí v rámci jiné nové a nepřipojené transakce.

Při spuštění ukázky se požadavky na operace a odpovědi zobrazí v okně konzoly klienta. Stisknutím klávesy ENTER v okně klienta klienta ukončete klienta.

Starting transaction
  Add(100,15.99) = 115.99
  Subtract(145,76.54) = 68.46
  Subtract(21.05,42.16) = -21.11
  Multiply(9,81.25) = 731.25
  Divide(22,7) = 3.14285714285714
  Completing transaction
Transaction committed
Press <ENTER> to terminate client.

Protokoly o žádostech o operaci služby jsou zobrazeny v okně konzoly služby. Stisknutím klávesy ENTER v okně klienta klienta ukončete klienta.

Press <ENTER> to terminate the service.
  Writing row to database: Adding 100 to 15.99
  Writing row to database: Subtracting 76.54 from 145
  Writing row to database: Subtracting 42.16 from 21.05
  Writing row to database: Multiplying 9 by 81.25
  Writing row to database: Dividing 22 by 7

Po úspěšném provedení se transakční rozsah klienta dokončí a všechny akce provedené v rámci tohoto rozsahu se potvrdí. Konkrétně je uvedeno 5 záznamů, které jsou trvalé v databázi služby. První 2 z těchto došlo v rámci rozsahu transakce klienta.

Pokud došlo k výjimce kdekoli v TransactionScope klienta, transakce se nemůže dokončit. To způsobí, že záznamy zaprotokolované v rámci tohoto rozsahu nebudou potvrzeny do databáze. Tento efekt lze pozorovat opakováním ukázkového spuštění po zakomentování volání dokončit vnější TransactionScope. Při takovém spuštění se protokolují pouze poslední 3 akce (od druhého Subtracta od požadavků Multiply a Divide), protože transakce klienta se k nim nedostala.

Jak nastavit, sestavit a spustit ukázku

  1. Pokud chcete sestavit verzi řešení v jazyce C# nebo Visual Basic .NET, postupujte podle pokynů v Sestavení ukázkových příkladů Windows Communication Foundation.

  2. Ujistěte se, že jste nainstalovali SQL Server Express Edition nebo SQL Server a že připojovací řetězec byl správně nastaven v konfiguračním souboru aplikace služby. Pokud chcete spustit ukázku bez použití databáze, nastavte hodnotu usingSql v konfiguračním souboru aplikace služby na false.

  3. Pokud chcete spustit ukázku v konfiguraci pro jeden počítač nebo pro více počítačů, postupujte podle pokynů v Spuštění ukázek Windows Communication Foundation.

    Poznámka

    Pro konfiguraci mezi počítači povolte koordinátor distribuovaných transakcí pomocí následujících pokynů a pomocí nástroje WsatConfig.exe ze sady Windows SDK povolte podporu sítě WCF Transactions. Informace o nastavení WsatConfig.exenaleznete v tématu Konfigurace WS-Atomic podpora transakcí.

Bez ohledu na to, jestli spustíte ukázku na stejném počítači nebo na různých počítačích, musíte nakonfigurovat microsoft Distributed Transaction Coordinator (MSDTC) tak, aby povolovala tok síťových transakcí a pomocí nástroje WsatConfig.exe povolte podporu sítě transakcí WCF.

Konfigurace koordinátoru distribuovaných transakcí (MSDTC) společnosti Microsoft pro podporu spuštění ukázky

  1. Na počítači služby se systémem Windows Server 2003 nebo Windows XP nakonfigurujte msDTC tak, aby povoloval příchozí síťové transakce podle těchto pokynů.

    1. V nabídce Start přejděte na Ovládací panely, poté na Nástroje pro správua nakonec na Služby komponent.

    2. Rozbalte Component Services. Otevřete složku Computers.

    3. Klepněte pravým tlačítkem myši Můj počítač a vyberte Vlastnosti.

    4. Na kartě MSDTC klikněte na tlačítko Konfigurace zabezpečení.

    5. Zkontrolujte přístup DTC k síti a Povolit příchozí.

    6. Klepněte na tlačítko OKa potom klepněte na tlačítko Ano restartujte službu MSDTC.

    7. Kliknutím na tlačítko OK dialogové okno zavřete.

  2. Na počítači služby se systémem Windows Server 2008 nebo Windows Vista nakonfigurujte msDTC tak, aby povoloval příchozí síťové transakce podle těchto pokynů.

    1. V nabídce Start přejděte na Ovládací panely, poté Nástroje pro správua nakonec Služby komponent.

    2. Rozbalte Component Services. Otevřete složku Computers. Vyberte Koordinátor distribuovaných transakcí.

    3. Klikněte pravým tlačítkem na koordinátora DTC a vyberte Vlastnosti.

    4. Na kartě Zabezpečení zaškrtněte políčko Síťový přístup DTC a Povolit příchozí.

    5. Klepněte na tlačítko OKa potom klepněte na tlačítko Ano restartujte službu MSDTC.

    6. Kliknutím na tlačítko OK dialogové okno zavřete.

  3. Na klientském počítači nakonfigurujte MSDTC tak, aby umožňoval odchozí síťové transakce:

    1. V nabídce Start přejděte na Control Panel, poté na Nástroje pro správu, a nakonec na Služby komponent.

    2. Klepněte pravým tlačítkem myši Můj počítač a vyberte Vlastnosti.

    3. Na kartě MSDTC klepněte na tlačítko Konfigurace zabezpečení.

    4. Zkontrolujte přístup DTC k síti a povolit odchozí připojení.

    5. Klepněte na tlačítko OKa potom klepněte na tlačítko Ano restartujte službu MSDTC.

    6. Kliknutím na tlačítko OK dialogové okno zavřete.