WS-TransaktionsflussWS Transaction Flow

In diesem Beispiel werden die Verwendung einer clientkoordinierten Transaktion und die Client- und Serveroptionen für den Transaktionsfluss unter Verwendung des WS-Atomic-Transaktionsprotokolls oder des OleTransactions-Protokolls erläutert.This sample demonstrates the use of a client-coordinated transaction and the client and server options for transaction flow using either the WS-Atomic Transaction or OleTransactions protocol. Dieses Beispiel basiert auf der Einstieg , implementiert einen rechnerdienst jedoch die Vorgänge zum Veranschaulichen der Verwendung von attributiert sind die TransactionFlowAttribute mit der TransactionFlowOption Enumeration, um zu bestimmen, welche Transaktion Grad Ablauf aktiviert ist.This sample is based on the Getting Started that implements a calculator service but the operations are attributed to demonstrate the use of the TransactionFlowAttribute with the TransactionFlowOption enumeration to determine to what degree transaction flow is enabled. Innerhalb des Bereichs des Transaktionsflusses wird ein Protokoll der angeforderten Vorgänge in eine Datenbank geschrieben. Dieses bleibt dort erhalten, bis die clientkoordinierte Transaktion fertiggestellt wurde. Wenn die Clienttransaktion nicht fertiggestellt wird, stellt die Webdiensttransaktion sicher, dass die entsprechenden Aktualisierungen der Datenbank nicht ausgeführt werden.Within the scope of the flowed transaction, a log of the requested operations is written to a database and persists until the client coordinated transaction has completed - if the client transaction does not complete, the Web service transaction ensures that the appropriate updates to the database are not committed.

Hinweis

Die Setupprozedur und die Buildanweisungen für dieses Beispiel befinden sich am Ende dieses Themas.The setup procedure and build instructions for this sample are located at the end of this topic.

Nach der Initiierung einer Verbindung zu dem Dienst und einer Transaktion greift der Client auf mehrere Dienstvorgänge zu.After initiating a connection to the service and a transaction, the client accesses several service operations. Der Vertrag für den Dienst ist folgendermaßen definiert, dabei veranschaulicht jeder der Vorgänge eine andere Einstellung für die TransactionFlowOption.The contract for the service is defined as follows with each of the operations demonstrating a different setting for the 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);   
}  

Auf diese Weise werden die Vorgänge in der Reihenfolge, in der sie verarbeitet werden sollten, definiert:This defines the operations in the order they are to be processed:

  • Eine Add-Vorgangsanforderung muss einen Transaktionsfluss beinhalten.An Add operation request must include a flowed transaction.

  • Eine Subtract-Vorgangsanforderung kann einen Transaktionsfluss beinhalten.A Subtract operation request may include a flowed transaction.

  • Eine Multiply-Vorgangsanforderung darf keinen Transaktionsfluss durch die explizite NotAllowed-Einstellung beinhalten.A Multiply operation request must not include a flowed transaction through the explicit NotAllowed setting.

  • Eine Divide-Vorgangsanforderung darf keinen Transaktionsfluss durch die Auslassung eines TransactionFlow-Attributs beinhalten.A Divide operation request must not include a flowed transaction through the omission of a TransactionFlow attribute.

Zum Aktivieren des Transaktionsflusses, Bindungen, mit der <TransactionFlow > aktiviert-Eigenschaft muss neben den Attributen des entsprechenden Vorgang verwendet werden.To enable transaction flow, bindings with the <transactionFlow> property enabled must be used in addition to the appropriate operation attributes. In diesem Beispiel macht die Dienstkonfiguration zusätzlich zu einem Metadatenaustausch-Endpunkt einen TCP-Endpunkt und einen HTTP-Endpunkt verfügbar.In this sample, the service's configuration exposes a TCP endpoint and an HTTP endpoint in addition to a Metadata Exchange endpoint. Der TCP-Endpunkt und den HTTP-Endpunkt verwendet die folgenden Bindungen, beide haben die <TransactionFlow > Eigenschaft aktiviert.The TCP endpoint and the HTTP endpoint use the following bindings, both of which have the <transactionFlow> property enabled.

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

Hinweis

Die vom System bereitgestellte netTcpBinding ermöglicht die Festlegung des transactionProtocol, während die vom System bereitgestellte wsHttpBinding nur das interoperablere WSAtomicTransactionOctober2004-Protokoll verwendet.The system-provided netTcpBinding allows specification of the transactionProtocol whereas the system-provided wsHttpBinding uses only the more interoperable WSAtomicTransactionOctober2004 protocol. Die OleTransactions Protokoll nur für verfügbar ist, verwenden von Windows Communication Foundation (WCF)-Clients.The OleTransactions protocol is only available for use by Windows Communication Foundation (WCF) clients.

Für die Klasse, die die ICalculator-Schnittstelle implementiert, werden alle Methoden mit auf TransactionScopeRequired festgelegter true-Eigenschaft attributiert.For the class that implements the ICalculator interface, all of the methods are attributed with TransactionScopeRequired property set to true. Diese Einstellung deklariert, dass alle innerhalb der Methode ausgeführten Aktionen innerhalb des Bereichs einer Transaktion auftreten.This setting declares that all actions taken within the method occur within the scope of a transaction. In diesem Fall beinhalten die ausgeführten Aktionen auch Aufzeichnung in der Protokolldatenbank.In this case, the actions taken include recording to the log database. Wenn die Vorgangsanforderung einen Transaktionsfluss beinhaltet, treten die Aktionen innerhalb des Bereichs der eingehenden Transaktion auf, oder es wird automatisch ein neuer Transaktionsbereich erstellt.If the operation request includes a flowed transaction then the actions occur within the scope of the incoming transaction or a new transaction scope is automatically generated.

Hinweis

Die TransactionScopeRequired-Eigenschaft definiert das Verhalten lokal in Bezug auf die Implementierungen der Dienstmethode und definiert nicht die Fähigkeit des Clients für oder die Notwendigkeit eines Transaktionsflusses.The TransactionScopeRequired property defines behavior local to the service method implementations and does not define the client's ability to or requirement for flowing a transaction.

// 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  
}  

Auf dem Client werden die TransactionFlowOption-Einstellungen des Diensts für die Vorgänge in der generierten Definition des Clients für die ICalculator-Schnittstelle wiedergegeben.On the client, the service's TransactionFlowOption settings on the operations are reflected in the client's generated definition of the ICalculator interface. Außerdem werden die transactionFlow-Eigenschaftseinstellungen des Diensts in der Anwendungskonfiguration des Clients wiedergegeben.Also, the service's transactionFlow property settings are reflected in the client's application configuration. Der Client kann den Transport und das Protokoll auswählen, indem er den entsprechenden endpointConfigurationName auswählt.The client can select the transport and protocol by selecting the appropriate endpointConfigurationName.

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

Hinweis

Das beobachtete Verhalten dieses Beispiels ist das gleiche, unabhängig davon, welches Protokoll oder welcher Transport ausgewählt wird.The observed behavior of this sample is the same no matter which protocol or transport is chosen.

Nach der Initiierung der Verbindung zu dem Dienst erstellt der Client einen neuen TransactionScope um die Aufrufe der Dienstvorgänge.Having initiated the connection to the service, the client creates a new TransactionScope around the calls to the service operations.

// 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");  

Die Aufrufe der Vorgänge sehen folgendermaßen aus:The calls to the operations are as follows:

  • Die Add-Anforderung übergibt die erforderliche Transaktion an den Dienst, und die Aktionen des Diensts treten innerhalb des Bereichs der Transaktion des Clients auf.The Add request flows the required transaction to the service and the service's actions occur within the scope of the client's transaction.

  • Die erste Subtract-Anforderung übergibt die zulässige Transaktion ebenfalls an den Dienst, und die Aktionen des Diensts treten erneut innerhalb des Bereichs der Transaktion des Clients auf.The first Subtract request also flows the allowed transaction to the service and again the service's actions occur within the scope of the client's transaction.

  • Die zweite Subtract-Anforderung wird innerhalb eines neuen Transaktionsbereichs ausgeführt, der mit der TransactionScopeOption.Suppress-Option deklariert wird.The second Subtract request is performed within a new transaction scope declared with the TransactionScopeOption.Suppress option. Auf diese Weise wird die initiale äußere Transaktion des Clients unterdrückt, und die Anforderung übergibt keine Transaktion an den Dienst.This suppresses the client's initial outer transaction and the request does not flow a transaction to the service. Mithilfe dieses Verfahrens kann ein Client explizit deaktiviert werden, und es wird verhindert, dass eine Transaktion an einen Dienst übergeben wird, wenn diese nicht erforderlich ist.This approach allows a client to explicitly opt-out of and protect against flowing a transaction to a service when that is not required. Die Aktionen des Diensts treten innerhalb des Bereichs einer neuen und unverbundenen Transaktion auf.The service's actions occur within the scope of a new and unconnected transaction.

  • Der Multiply -Anforderung übergibt keine Transaktion an den Dienst aus, da die generierte Definition der ICalculator Schnittstelle enthält eine TransactionFlowAttribute festgelegt TransactionFlowOption NotAllowed.The Multiply request does not flow a transaction to the service because the client's generated definition of the ICalculator interface includes a TransactionFlowAttribute set to TransactionFlowOptionNotAllowed.

  • Die Divide-Anforderung übergibt keine Transaktion an den Dienst, da die generierte Definition der ICalculator-Schnittstelle wiederum kein TransactionFlowAttribute beinhaltet.The Divide request does not flow a transaction to the service because again the client's generated definition of the ICalculator interface does not include a TransactionFlowAttribute. Die Aktionen des Diensts treten erneut innerhalb des Bereichs einer anderen neuen und unverbundenen Transaktion auf.The service's actions again occur within the scope of another new and unconnected transaction.

Wenn Sie das Beispiel ausführen, werden die Anforderungen und Antworten für den Vorgang im Clientkonsolenfenster angezeigt.When you run the sample, the operation requests and responses are displayed in the client console window. Drücken Sie im Clientfenster die EINGABETASTE, um den Client zu schließen.Press ENTER in the client window to shut down the client.

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.  

Die Protokollierung der Dienstvorgangsanforderungen wird im Konsolenfenster des Diensts angezeigt.The logging of the service operation requests are displayed in the service's console window. Drücken Sie im Clientfenster die EINGABETASTE, um den Client zu schließen.Press ENTER in the client window to shut down the client.

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  

Nach einer erfolgreichen Ausführung wird der Transaktionsbereich des Clients abgeschlossen, und alle Aktionen innerhalb des Bereichs werden ausgeführt.After a successful execution, the client's transaction scope completes and all actions taken within that scope are committed. Vor allem werden die erwähnten fünf Datensätze in der Datenbank des Diensts beibehalten.Specifically, the noted 5 records are persisted in the service's database. Die beiden ersten sind innerhalb des Bereichs der Transaktion des Clients aufgetreten.The first 2 of these have occurred within the scope of the client's transaction.

Wenn im TransactionScope des Clients eine Ausnahme aufgetreten ist, kann die Transaktion nicht abgeschlossen werden.If an exception occurred anywhere within the client's TransactionScope then the transaction cannot complete. Dies führt dazu, dass die innerhalb des Bereichs protokollierten Datensätze nicht an die Datenbank übergeben werden.This causes the records logged within that scope to not be committed to the database. Dieser Effekt kann beobachtet werden, wenn das Beispiel erneut ausgeführt wird, nachdem der Aufruf zum Abschließen des äußeren TransactionScope auskommentiert wurde.This effect can be observed by repeating the sample run after commenting out the call to complete the outer TransactionScope. Bei einer solchen Ausführung werden nur die letzen drei Aktionen protokolliert (die zweite Subtract-, die Multiply- und die Divide-Anforderung), da die Clienttransaktion nicht an diese übergeben wurde.On such a run, only the last 3 actions (from the second Subtract, the Multiply and the Divide requests) are logged because the client transaction did not flow to those.

So können Sie das Beispiel einrichten, erstellen und ausführenTo set up, build, and run the sample

  1. Führen Sie zum Erstellen der C#- oder Visual Basic-Version der Lösung die Anweisungen im Erstellen der Windows Communication Foundation-BeispieleTo build the C# or Visual Basic .NET version of the solution, follow the instructions in Building the Windows Communication Foundation Samples

  2. Vergewissern Sie sich, dass SQL Server Express Edition oder SQL Server installiert ist. Stellen Sie außerdem sicher, dass die Verbindungszeichenfolge in der Anwendungskonfigurationsdatei des Diensts ordnungsgemäß festgelegt ist.Ensure that you have installed SQL Server Express Edition or SQL Server, and that the connection string has been correctly set in the service’s application configuration file. Wenn Sie das Beispiel ohne eine Datenbank ausführen möchten, legen Sie den usingSql-Wert in der Anwendungskonfigurationsdatei des Diensts auf false fest.To run the sample without using a database, set the usingSql value in the service’s application configuration file to false

  3. Um das Beispiel in einer einzelnen oder computerübergreifenden Konfiguration ausführen möchten, folgen Sie den Anweisungen Ausführen der Windows Communication Foundation-Beispiele.To run the sample in a single- or cross-machine configuration, follow the instructions in Running the Windows Communication Foundation Samples.

    Hinweis

    Aktivieren Sie bei einer computerübergreifenden Konfiguration Distributed Transaction Coordinator entsprechend den nachfolgenden Anweisungen, und aktivieren Sie mit dem Tool WsatConfig.exe aus dem Windows SDK die Netzwerkunterstützung von WCF-Transaktionen.For cross-machine configuration, enable the Distributed Transaction Coordinator using the instructions below, and use the WsatConfig.exe tool from the Windows SDK to enable WCF Transactions network support. Finden Sie unter WS-AtomicTransaction-Unterstützung konfigurieren Informationen zum Einrichten von WsatConfig.exe.See Configuring WS-Atomic Transaction Support for information on setting up WsatConfig.exe.

Ob Sie das Beispiel auf demselben Computer oder auf anderen Computern ausführen, müssen Sie den Microsoft Distributed Transaction Coordinator (MSDTC) zum Netzwerk Transaktionsfluss aktivieren und verwenden das Tool WsatConfig.exe die Netzwerkunterstützung von WCF-Transaktionen aktivieren konfigurieren.Whether you run the sample on the same computer or on different computers, you must configure the Microsoft Distributed Transaction Coordinator (MSDTC) to enable network transaction flow and use the WsatConfig.exe tool to enable WCF transactions network support.

So konfigurieren Sie Microsoft Distributed Transaction Coordinator (MSDTC) zum Ausführen des BeispielsTo configure the Microsoft Distributed Transaction Coordinator (MSDTC) to support running the sample

  1. Konfigurieren Sie MSDTC auf einem Dienstcomputer unter Windows Server 2003 oder Windows XP entsprechend den folgenden Anweisungen so, dass eingehende Netzwerktransaktionen zugelassen werden.On a service machine running Windows Server 2003 or Windows XP, configure MSDTC to allow incoming network transactions by following these instructions.

    1. Aus der starten Menü, navigieren Sie zu Systemsteuerung, klicken Sie dann Verwaltung, und klicken Sie dann Komponentendienste.From the Start menu, navigate to Control Panel, then Administrative Tools, and then Component Services.

    2. Erweitern Sie Komponentendienste.Expand Component Services. Öffnen der Computer Ordner.Open the Computers folder.

    3. Mit der rechten Maustaste Arbeitsplatz , und wählen Sie Eigenschaften.Right-click My Computer and select Properties.

    4. Auf der MSDTC auf Sicherheitskonfiguration.On the MSDTC tab, click Security Configuration.

    5. Überprüfen Sie DTC-Netzwerkzugriff und zulassen eingehenden.Check Network DTC Access and Allow Inbound.

    6. Klicken Sie auf OK, klicken Sie dann auf Ja den MSDTC-Dienst neu starten.Click OK, then click Yes to restart the MSDTC service.

    7. Klicken Sie auf OK, um das Dialogfeld zu schließen.Click OK to close the dialog box.

  2. Konfigurieren Sie MSDTC auf einem Dienstcomputer unter Windows Server 2008 oder Windows Vista entsprechend den folgenden Anweisungen so, dass eingehende Netzwerktransaktionen zugelassen werden.On a service machine running Windows Server 2008 or Windows Vista, configure MSDTC to allow incoming network transactions by following these instructions.

    1. Aus der starten Menü, navigieren Sie zu Systemsteuerung, klicken Sie dann Verwaltung, und klicken Sie dann Komponentendienste.From the Start menu, navigate to Control Panel, then Administrative Tools, and then Component Services.

    2. Erweitern Sie Komponentendienste.Expand Component Services. Öffnen der Computer Ordner.Open the Computers folder. Wählen Sie Distributed Transaction Coordinator.Select Distributed Transaction Coordinator.

    3. Mit der rechten Maustaste Distributed Transaction Coordinator , und wählen Sie Eigenschaften.Right-click DTC Coordinator and select Properties.

    4. Auf der Sicherheit Registerkarte DTC-Netzwerkzugriff und eingehende zulassen.On the Security tab, check Network DTC Access and Allow Inbound.

    5. Klicken Sie auf OK, klicken Sie dann auf Ja den MSDTC-Dienst neu starten.Click OK, then click Yes to restart the MSDTC service.

    6. Klicken Sie auf OK, um das Dialogfeld zu schließen.Click OK to close the dialog box.

  3. Konfigurieren Sie auf dem Clientcomputer MSDTC zum Zulassen von ausgehenden Netzwerktransaktionen:On the client machine, configure MSDTC to allow outgoing network transactions:

    1. Aus der starten Menü, navigieren Sie zu Control Panel, klicken Sie dann Verwaltung, und klicken Sie dann Komponentendienste.From the Start menu, navigate to Control Panel, then Administrative Tools, and then Component Services.

    2. Mit der rechten Maustaste Arbeitsplatz , und wählen Sie Eigenschaften.Right-click My Computer and select Properties.

    3. Auf der MSDTC auf Sicherheitskonfiguration.On the MSDTC tab, click Security Configuration.

    4. Überprüfen Sie DTC-Netzwerkzugriff und ausgehende zulassen.Check Network DTC Access and Allow Outbound.

    5. Klicken Sie auf OK, klicken Sie dann auf Ja den MSDTC-Dienst neu starten.Click OK, then click Yes to restart the MSDTC service.

    6. Klicken Sie auf OK, um das Dialogfeld zu schließen.Click OK to close the dialog box.

Wichtig

Die Beispiele sind möglicherweise bereits auf dem Computer installiert.The samples may already be installed on your machine. Suchen Sie nach dem folgenden Verzeichnis (Standardverzeichnis), bevor Sie fortfahren.Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

Wenn dieses Verzeichnis nicht vorhanden ist, fahren Sie mit Windows Communication Foundation (WCF) und Windows Workflow Foundation (WF) Samples for .NET Framework 4 aller Windows Communication Foundation (WCF) herunterladen und WFWF Beispiele.If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WFWF samples. Dieses Beispiel befindet sich im folgenden Verzeichnis.This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WCF\Basic\Binding\WS\TransactionFlow