DiensttransaktionsverhaltenService Transaction Behavior

In diesem Beispiel werden die Verwendung einer clientkoordinierten Transaktion und die Einstellungen von ServiceBehaviorAttribute und OperationBehaviorAttribute zum Steuern des Diensttransaktionsverhaltens veranschaulicht.This sample demonstrates the use of a client-coordinated transaction and the settings of ServiceBehaviorAttribute and OperationBehaviorAttribute to control service transaction behavior. Dieses Beispiel basiert auf der Einstieg , implementiert einen rechnerdienst, aber wird erweitert, um das Verwalten einer Server-Protokoll der ausgeführten Vorgänge in einer Datenbanktabelle und eines zustandsbehafteten Summe für die rechnervorgänge ausgeführt.This sample is based on the Getting Started that implements a calculator service, but is extended to maintain a server log of the performed operations in a database table and a stateful running total for the calculator operations. Beibehaltene Schreibvorgänge in der Serverprotokolltabelle sind abhängig vom Ergebnis einer clientkoordinierten Transaktion. Wenn die Clienttransaktion nicht abgeschlossen wird, stellt die Webdiensttransaktion sicher, dass die Aktualisierungen der Datenbank nicht ausgeführt werden.Persisted writes to the server log table are dependent upon the outcome of a client coordinated transaction - if the client transaction does not complete, the Web service transaction ensures that the 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.

Der Vertrag für den Dienst definiert, dass für alle Vorgänge eine Transaktion mit Anforderungen übergeben werden muss:The contract for the service defines that all of the operations require a transaction to be flowed with requests:

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

Zum Aktivieren des eingehenden Transaktionsflusses wird der Dienst mit der vom System bereitgestellten wsHttpBinding konfiguriert, wobei das transactionFlow-Attribut auf true festgelegt ist.To enable the incoming transaction flow, the service is configured with the system-provided wsHttpBinding with the transactionFlow attribute set to true. Diese Bindung verwendet das interoperable WSAtomicTransactionOctober2004-Protokoll:This binding uses the interoperable WSAtomicTransactionOctober2004 protocol:

<bindings>  
  <wsHttpBinding>  
    <binding name="transactionalBinding" transactionFlow="true" />  
  </wsHttpBinding>  
</bindings>  

Nach dem Initiieren einer Verbindung mit dem Dienst und einer Transaktion greift der Client auf mehrere Dienstvorgänge im Bereich der Transaktion zu, schließt die Transaktion ab und trennt die Verbindung:After initiating both a connection to the service and a transaction, the client accesses several service operations within the scope of that transaction and then completes the transaction and closes the connection:

// Create a client  
CalculatorClient client = new CalculatorClient();  

// Create a transaction scope with the default isolation level of Serializable  
using (TransactionScope tx = new TransactionScope())  
{  
    Console.WriteLine("Starting transaction");  

    // Call the Add service operation.  
    double value = 100.00D;  
    Console.WriteLine("  Adding {0}, running total={1}",  
                                        value, client.Add(value));  

    // Call the Subtract service operation.  
    value = 45.00D;  
    Console.WriteLine("  Subtracting {0}, running total={1}",  
                                        value, client.Subtract(value));  

    // Call the Multiply service operation.  
    value = 9.00D;  
    Console.WriteLine("  Multiplying by {0}, running total={1}",  
                                        value, client.Multiply(value));  

    // Call the Divide service operation.  
    value = 15.00D;  
    Console.WriteLine("  Dividing by {0}, running total={1}",  
                                        value, client.Divide(value));  

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

Console.WriteLine("Transaction committed");  

// Closing the client gracefully closes the connection and cleans up resources  
client.Close();  

Bei dem Dienst gibt es drei Attribute, die Auswirkungen auf das Diensttransaktionsverhalten haben. Dies geschieht wie folgt:On the service, there are three attributes that affect the service transaction behavior, and they do so in the following ways:

  • Für ServiceBehaviorAttribute:On the ServiceBehaviorAttribute:

    • Die TransactionTimeout-Eigenschaft gibt den Zeitraum an, innerhalb dessen eine Transaktion abgeschlossen werden muss.The TransactionTimeout property specifies the time period within which a transaction must complete. In diesem Beispiel ist sie auf 30 Sekunden festgelegt.In this sample it is set to 30 seconds.

    • Die TransactionIsolationLevel-Eigenschaft gibt die Isolationsstufe an, die der Dienst unterstützt.The TransactionIsolationLevel property specifies the isolation level that the service supports. Dies ist zur Übereinstimmung mit der Isolationsstufe des Clients erforderlich.This is required to match the client's isolation level.

    • Die ReleaseServiceInstanceOnTransactionComplete-Eigenschaft legt fest, ob die Dienstinstanz beim Abschluss einer Transaktion wiederverwendet wird.The ReleaseServiceInstanceOnTransactionComplete property specifies whether the service instance is recycled when a transaction completes. Durch das Festlegen auf false behält der Dienst die gleiche Dienstinstanz über die Vorgangsanforderungen hinweg bei.By setting it to false, the service maintains the same service instance across the operation requests. Dies ist für das Beibehalten der laufenden Gesamtsumme erforderlich.This is required to maintain the running total. Beim Festlegen auf true wird nach jeder abgeschlossenen Aktion eine neue Instanz generiert.If set to true, a new instance is generated after each completed action.

    • Die TransactionAutoCompleteOnSessionClose-Eigenschaft gibt an, ob ausstehende Transaktionen abgeschlossen werden, wenn die Sitzung geschlossen wird.The TransactionAutoCompleteOnSessionClose property specifies whether outstanding transactions are completed when the session closes. Durch Festlegen auf false, die einzelnen Vorgänge sind erforderlich, um entweder die OperationBehaviorAttribute``TransactionAutoComplete Eigenschaft, um true oder für die explizit einen Aufruf der SetTransactionComplete Methode, um Transaktionen abzuschließen.By setting it to false, the individual operations are required to either set the OperationBehaviorAttribute``TransactionAutoComplete property to true or to explicitly require a call to the SetTransactionComplete method to complete transactions. In diesem Beispiel werden beide Ansätze veranschaulicht.This sample demonstrates both approaches.

  • Für ServiceContractAttribute:On the ServiceContractAttribute:

    • Die SessionMode-Eigenschaft gibt an, ob der Dienst die entsprechenden Anforderungen in eine logische Sitzung korreliert.The SessionMode property specifies whether the service correlates the appropriate requests into a logical session. Da dieser Dienst Vorgänge umfasst, bei denen die OperationBehaviorAttribute TransactionAutoComplete-Eigenschaft auf false festgelegt ist (Multiply und Divide), muss SessionMode.Required angegeben werden.Because this service includes operations where the OperationBehaviorAttribute TransactionAutoComplete property is set to false (Multiply and Divide), SessionMode.Required must be specified. Der Multiply-Vorgang schließt seine Transaktion beispielsweise nicht ab und benötigt stattdessen den Abschluss eines späteren Aufrufs von Divide mithilfe der SetTransactionComplete-Methode. Der Dienst muss bestimmen können, dass diese Vorgänge in der gleichen Sitzung ausgeführt werden.For example, the Multiply operation does not complete its transaction and instead relies upon a later call to Divide to complete using the SetTransactionComplete method; the service must be able to determine that these operations are occurring within the same session.
  • Für OperationBehaviorAttribute:On the OperationBehaviorAttribute:

    • Die TransactionScopeRequired-Eigenschaft gibt an, ob die Aktionen des Vorgangs innerhalb eines Transaktionsbereichs ausgeführt werden sollen.The TransactionScopeRequired property specifies whether the operation's actions should be executed within a transaction scope. Dies ist für alle Vorgänge in diesem Beispiel auf true festgelegt, und da der Client seine Transaktion auf alle Vorgänge überträgt, treten die Aktionen im Bereich dieser Clienttransaktion auf.This is set to true for all operations in this sample and, because the client flows its transaction to all operations, the actions occur within the scope of that client transaction.

    • Die TransactionAutoComplete-Eigenschaft legt fest, ob die Transaktion, in der die Methode ausgeführt wird, automatisch abgeschlossen wird, wenn keine nicht behandelten Ausnahmen ausgelöst werden.The TransactionAutoComplete property specifies whether the transaction in which the method executes is automatically completed if no unhandled exceptions occur. Wie oben beschrieben, ist dies für den Add-Vorgang und den Subtract-Vorgang auf true festgelegt, für den Multiply-Vorgang und den Divide-Vorgang jedoch auf false.As previously described, this is set to true for the Add and Subtract operations but false for the Multiply and Divide operations. Der Add-Vorgang und der Subtract-Vorgang schließen die Aktionen automatisch ab, der Divide-Vorgang schließt seine Aktionen durch einen expliziten Aufruf der SetTransactionComplete-Methode ab, und der Multiply-Vorgang schließt die Aktionen nicht ab, sondern benötigt einen späteren Aufruf, beispielsweise von Divide, zum Abschließen der Aktionen.The Add and Subtract operations complete their actions automatically, the Divide completes its actions through an explicit call to the SetTransactionComplete method, and the Multiply does not complete its actions but instead relies upon and requires a later call, such as to Divide, to complete the actions.

Die attributierte Dienstimplementierung lautet wie folgt:The attributed service implementation is as follows:

[ServiceBehavior(  
    TransactionIsolationLevel = System.Transactions.IsolationLevel.Serializable,  
    TransactionTimeout = "00:00:30",  
    ReleaseServiceInstanceOnTransactionComplete = false,  
    TransactionAutoCompleteOnSessionClose = false)]  
public class CalculatorService : ICalculator  
{  
    double runningTotal;  

    public CalculatorService()  
    {  
        Console.WriteLine("Creating new service instance...");  
    }  

    [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]  
    public double Add(double n)  
    {  
        RecordToLog(String.Format(CultureInfo.CurrentCulture, "Adding {0} to {1}", n, runningTotal));  
        runningTotal = runningTotal + n;  
        return runningTotal;  
    }  

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

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

    [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = false)]  
    public double Divide(double n)  
    {  
        RecordToLog(String.Format(CultureInfo.CurrentCulture, "Dividing {0} by {1}", runningTotal, n));  
        runningTotal = runningTotal / n;  
        OperationContext.Current.SetTransactionComplete();  
        return runningTotal;  
    }  

    // Logging method ommitted for brevity  
}   

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  
Performing calculations...  
  Adding 100, running total=100  
  Subtracting 45, running total=55  
  Multiplying by 9, running total=495  
  Dividing by 15, running total=33  
  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 service.  
Creating new service instance...  
  Writing row 1 to database: Adding 100 to 0  
  Writing row 2 to database: Subtracting 45 from 100  
  Writing row 3 to database: Multiplying 55 by 9  
  Writing row 4 to database: Dividing 495 by 15  

Zusätzlich zur laufenden Summe der Berechnungen erstellt der Dienst einen Bericht über die Instanzenerstellung (eine Instanz zu diesem Beispiel) und protokolliert die Vorgangsanforderungen in einer Datenbank.Note that in addition to keeping the running total of the calculations, the service reports the creation of instances (one instance for this sample) and logs the operation requests to a database. Da alle Anforderung die Transaktion des Clients übergeben, führt ein Fehler beim Abschließen dieser Transaktion zu einem Rollback aller Datenbankvorgänge.Because all of the requests flow the client's transaction, any failure to complete that transaction results in all of the database operations being rolled back. Dies kann auf mehrere Arten veranschaulicht werden:This can be demonstrated in a number of ways:

  • Kommentieren Sie den Aufruf von tx.Complete() durch den Client aus, und führen Sie das Beispiel erneut aus. So verlässt der Client den Transaktionsbereich, ohne die Transaktion abzuschließen.Comment out the client's call to tx.Complete() and rerun - this results in the client exiting the transaction scope without completing its transaction.

  • Kommentieren Sie den Aufruf des Divide-Dienstvorgangs aus. Dies führt dazu, dass die vom Multiply-Vorgang initiierte Aktion nicht abgeschlossen werden kann. Die Transaktion des Clients kann somit auch nicht abgeschlossen werden.Comment out the call to the Divide service operation - this results prevent the action initiated by the Multiply operation from completing and thus the client's transaction ultimately also fails to complete.

  • Lösen Sie an einer beliebigen Stelle im Transaktionsbereich des Clients eine nicht behandelte Ausnahme aus. Diese führt ebenfalls dazu, dass der Client die Transaktion nicht abschließen kann.Throw an unhandled exception anywhere in the client's transaction scope - this similarly prevents the client from completing its transaction.

Alle diese Aktionen führen dazu, dass die in diesem Bereich ausgeführten Vorgänge beendet werden und dass die Anzahl der in der Datenbank beibehaltenen Zeilen nicht inkrementiert wird.The result of any of these is that none of the operations performed within that scope are committed and the count of rows persisted to the database do not increment.

Hinweis

Während des Buildprozesses wird die Datenbankdatei in den bin-Ordner kopiert.As part of the build process the database file is copied to the bin folder. Sie müssen diese Kopie der Datenbankdatei betrachten, um die im Protokoll gespeicherten Zeilen zu ermitteln, und nicht die Datei im Visual Studio-Projekt.You must look at that copy of the database file to observe the rows that are persisted to the log rather than the file that is included in the Visual Studio project.

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

  1. Stellen Sie sicher, dass SQL Server 2005 Express Edition oder SQL Server 2005 installiert ist.Ensure that you have installed SQL Server 2005 Express Edition or SQL Server 2005. In der Datei App.config des Diensts ist connectionString für die Datenbank möglicherweise festgelegt oder die Datenbankinteraktionen sind deaktiviert, indem der usingSql-Wert für appSettings auf false festgelegt ist.In the service's App.config file, the database connectionString may be set or the database interactions may be disabled by setting the appSettings usingSql value to false.

  2. Um die C#- oder Visual Basic .NET-Edition der Projektmappe zu erstellen, befolgen Sie die unter Building the Windows Communication Foundation Samplesaufgeführten Anweisungen.To build the C# or Visual Basic .NET edition of the solution, follow the instructions in Building the Windows Communication Foundation Samples.

  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.

Wenn Sie das Beispiel computerübergreifend ausführen, müssen Sie konfigurieren den Microsoft Distributed Transaction Coordinator (MSDTC) zum Netzwerk Transaktionsfluss aktivieren und Verwenden des Tools WsatConfig.exe zum Netzwerk der Windows Communication Foundation (WCF)-Transaktionen aktivieren unterstützt.If you run the sample across machines, you must configure the Microsoft Distributed Transaction Coordinator (MSDTC) to enable network transaction flow and use the WsatConfig.exe tool to enable Windows Communication Foundation (WCF) transactions network support.

So konfigurieren Sie Microsoft Distributed Transaction Coordinator (MSDTC) zum Ausführen des Beispiels computerübergreifendTo configure the Microsoft Distributed Transaction Coordinator (MSDTC) to support running the sample across machines

  1. Konfigurieren Sie auf dem Dienstcomputer MSDTC zum Zulassen von eingehenden Netzwerktransaktionen.On the service machine, configure MSDTC to allow incoming network transactions.

    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. 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 zulassen eingehenden.Check Network DTC Access and Allow Inbound.

    5. Klicken Sie auf Ja den MS DTC-Dienst neu, und klicken Sie dann auf OK.Click Yes to restart the MS DTC service and then click OK.

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

  2. Konfigurieren Sie auf dem Dienstcomputer und auf dem Clientcomputer die Windows-Firewall so, dass Microsoft Distributed Transaction Coordinator (MSDTC) in der Liste der ausgeschlossenen Anwendungen angezeigt wird:On the service machine and the client machine, configure the Windows Firewall to include the Microsoft Distributed Transaction Coordinator (MSDTC) to the list of excepted applications:

    1. Führen Sie die Windows-Firewall-Anwendung über die Systemsteuerung aus.Run the Windows Firewall application from Control Panel.

    2. Aus der Ausnahmen auf Programm hinzufügen.From the Exceptions tab, click Add Program.

    3. Navigieren Sie zum Ordner C:\WINDOWS\System32.Browse to the folder C:\WINDOWS\System32.

    4. Wählen Sie Msdtc.exe, und klicken Sie auf öffnen.Select Msdtc.exe and click Open.

    5. Klicken Sie auf OK schließen die Programm hinzufügen (Dialogfeld), und klicken Sie auf OK erneut aus, um das Windows-Firewall-Applet zu schließen.Click OK to close the Add Program dialog box, and click OK again to close the Windows Firewall applet.

  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 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. 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 Ja den MS DTC-Dienst neu, und klicken Sie dann auf OK.Click Yes to restart the MS DTC service and then click OK.

    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\Services\Behaviors\Transactions

Siehe auchSee Also