Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
TransactionFlow-exempel visar användningen av en klientkoordinerad transaktion och klient- och serveralternativen för transaktionsflödet med antingen protokollet WS-Atomic Transaction eller OleTransactions. Det här exemplet baseras på Komma igång som implementerar en kalkylatortjänst, men åtgärderna tillskrivs för att demonstrera användningen av TransactionFlowAttribute
med TransactionFlowOption uppräkning för att avgöra i vilken grad transaktionsflödet är aktiverat. Inom omfånget för den flödesbaserade transaktionen skrivs en logg över de begärda åtgärderna till en databas och bevaras tills den klientkoordinerade transaktionen har slutförts – om klienttransaktionen inte slutförs säkerställer webbtjänsttransaktionen att lämpliga uppdateringar av databasen inte har checkats in.
Not
Installationsproceduren och bygginstruktionerna för det här exemplet finns i slutet av det här avsnittet.
Efter att ha initierat en anslutning till tjänsten och en transaktion får klienten tillgång till flera tjänsteoperationer. Kontraktet för tjänsten definieras enligt följande med var och en av åtgärderna som visar en annan inställning för 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);
}
Detta definierar åtgärderna i den ordning de ska bearbetas:
En
Add
åtgärdsbegäran måste innehålla en flödestransaktion.En
Subtract
åtgärdsbegäran kan innehålla en flödestransaktion.En
Multiply
-begäran om åtgärd får inte innehålla en flödestransaktion genom den specifika inställningen NotAllowed.En
Divide
åtgärdsbegäran får inte innehålla en flödestransaktion genom utelämnandet av ettTransactionFlow
attribut.
För att aktivera transaktionsflödet måste bindningar med egenskapen <transactionFlow> användas utöver lämpliga åtgärdsattribut. I det här exemplet exponerar tjänstens konfiguration en TCP-slutpunkt och en HTTP-slutpunkt utöver en Metadata Exchange-slutpunkt. TCP-slutpunkten och HTTP-slutpunkten använder följande bindningar, som båda har egenskapen <transactionFlow> aktiverad.
<bindings>
<netTcpBinding>
<binding name="transactionalOleTransactionsTcpBinding"
transactionFlow="true"
transactionProtocol="OleTransactions"/>
</netTcpBinding>
<wsHttpBinding>
<binding name="transactionalWsatHttpBinding"
transactionFlow="true" />
</wsHttpBinding>
</bindings>
Not
Det systembaserade netTcpBinding tillåter specifikation av transactionProtocol, medan det systembaserade wsHttpBinding endast använder det mer driftskompatibla WSAtomicTransactionOctober2004-protokollet. OleTransactions-protokollet är endast tillgängligt för användning av WCF-klienter (Windows Communication Foundation).
För klassen som implementerar ICalculator
-gränssnittet tillskrivs alla metoder TransactionScopeRequired egenskap som är inställd på true
. Den här inställningen deklarerar att alla åtgärder som vidtas inom metoden sker inom omfånget för en transaktion. I det här fallet inkluderar de åtgärder som vidtas inspelning till loggdatabasen. Om åtgärdsbegäran innehåller en flödestransaktion sker åtgärderna inom omfånget för den inkommande transaktionen eller så genereras automatiskt ett nytt transaktionsomfång.
Not
Egenskapen TransactionScopeRequired definierar beteendet lokalt för tjänstmetodimplementeringarna och definierar inte klientens förmåga till eller krav för att flöda en transaktion.
// 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
}
På klienten återspeglas tjänstens TransactionFlowOption
inställningar för åtgärderna i klientens genererade definition av ICalculator
-gränssnittet. Dessutom återspeglas tjänstens transactionFlow
egenskapsinställningar i klientens programkonfiguration. Klienten kan välja transport och protokoll genom att välja lämplig endpointConfigurationName
.
// Create a client using either wsat or oletx endpoint configurations
CalculatorClient client = new CalculatorClient("WSAtomicTransaction_endpoint");
// CalculatorClient client = new CalculatorClient("OleTransactions_endpoint");
Not
Det observerade beteendet för det här exemplet är detsamma oavsett vilket protokoll eller vilken transport som väljs.
Efter att ha initierat anslutningen till tjänsten skapar klienten en ny TransactionScope
runt anropen till tjänstefunktionerna.
// 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");
Anropen till operationerna är följande:
Begäran
Add
vidarebefordrar den nödvändiga transaktionen till tjänsten, och tjänstens åtgärder sker inom ramen för klientens transaktion.Den första
Subtract
-begäran överför den tillåtna transaktionen till tjänsten, och återigen sker tjänstens åtgärder inom ramen för klientens transaktion.Den andra
Subtract
begäran utförs inom ett nytt transaktionsomfång som deklarerats med alternativetTransactionScopeOption.Suppress
. Detta undertrycker klientens initiala yttre transaktion och begäran överför inte en transaktion till tjänsten. Med den här metoden kan en klient uttryckligen välja bort och skydda mot att en transaktion flödar till en tjänst när det inte krävs. Tjänstens åtgärder sker inom ramen för en ny och oansluten transaktion.Multiply
-begäran överför inte en transaktion till tjänsten eftersom klientens genererade definition avICalculator
-gränssnittet har en TransactionFlowAttribute satt till TransactionFlowOptionNotAllowed
.Den
Divide
-begäran överför inte en transaktion till tjänsten, eftersom kundens genererade definition avICalculator
-gränssnittet återigen inte inkluderar någonTransactionFlowAttribute
. Tjänstens åtgärder sker igen inom ramen för en annan ny och oansluten transaktion.
När du kör exemplet visas åtgärdsbegäranden och svar i klientkonsolfönstret. Tryck på RETUR i klientfönstret för att stänga av klienten.
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.
Loggningen av tjänståtgärdsbegäranden visas i tjänstens konsolfönster. Tryck på RETUR i klientfönstret för att stänga av klienten.
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
Efter en lyckad körning slutförs klientens transaktionsomfång och alla åtgärder som vidtas inom det omfånget utförs. Mer specifikt lagras de angivna 5 posterna i tjänstens databas. De första två av dessa har inträffat inom omfånget för klientens transaktion.
Om ett undantag inträffade någonstans inom klientens TransactionScope
kan transaktionen inte slutföras. Detta medför att de poster som loggas inom det omfånget inte sparas i databasen. Den här effekten kan observeras genom att upprepa exempelkörningen när du har kommenterat ut anropet för att slutföra den yttre TransactionScope
. Vid en sådan körning loggas endast de tre sista åtgärderna (från den andra Subtract
, Multiply
och Divide
begäranden) eftersom klienttransaktionen inte flödade till dem.
Så här konfigurerar du, skapar och kör exemplet
Om du vill skapa C# eller Visual Basic .NET-versionen av lösningen följer du anvisningarna i Skapa Windows Communication Foundation-exempel.
Kontrollera att du har installerat SQL Server Express Edition eller SQL Server och att anslutningssträngen har angetts korrekt i tjänstens programkonfigurationsfil. Om du vill köra exemplet utan att använda en databas anger du värdet
usingSql
i tjänstens programkonfigurationsfil tillfalse
.Om du vill köra exemplet i en konfiguration med en eller flera datorer följer du anvisningarna i Köra Windows Communication Foundation-exempel.
Not
För konfiguration mellan datorer aktiverar du Distributed Transaction Coordinator med hjälp av anvisningarna nedan och använder verktyget WsatConfig.exe från Windows SDK för att aktivera nätverksstöd för WCF-transaktioner. Information om hur du konfigurerar WsatConfig.exefinns i Konfigurera WS-Atomic transaktionsstöd.
Oavsett om du kör exemplet på samma dator eller på olika datorer måste du konfigurera Microsoft Distributed Transaction Coordinator (MSDTC) för att aktivera nätverkstransaktionsflöde och använda verktyget WsatConfig.exe för att aktivera nätverksstöd för WCF-transaktioner.
Konfigurera Microsoft Distributed Transaction Coordinator (MSDTC) för att stödja körning av exemplet
På en tjänstdator som kör Windows Server 2003 eller Windows XP konfigurerar du MSDTC för att tillåta inkommande nätverkstransaktioner genom att följa dessa instruktioner.
Från menyn Start navigerar du till Kontrollpanelen, administrationsverktygoch sedan Component Services.
Expandera Component Services. Öppna mappen Computers.
Högerklicka på Min dator och välj Egenskaper.
På fliken MSDTC klickar du på Säkerhetskonfiguration.
Kontrollera för nätverks-DTC-åtkomst och Tillåt inkommande.
Klicka på OKoch klicka sedan på Ja för att starta om MSDTC-tjänsten.
Klicka på OK för att stänga dialogrutan.
På en tjänstdator som kör Windows Server 2008 eller Windows Vista konfigurerar du MSDTC för att tillåta inkommande nätverkstransaktioner genom att följa dessa instruktioner.
Från menyn Start navigerar du till Kontrollpanelen, administrationsverktygoch sedan Component Services.
Expandera Component Services. Öppna mappen Computers. Välj Distribuerad Transaktionskoordinator.
Högerklicka på DTC-koordinator och välj Egenskaper.
På fliken Security kontrollerar du Network DTC Access och Tillåt inkommande.
Klicka på OKoch klicka sedan på Ja för att starta om MSDTC-tjänsten.
Klicka på OK för att stänga dialogrutan.
På klientdatorn konfigurerar du MSDTC så att utgående nätverkstransaktioner tillåts:
Från menyn Start navigerar du till
Control Panel
, administrationsverktygoch komponenttjänster.Högerklicka på Min dator och välj Egenskaper.
På fliken MSDTC klickar du på Säkerhetskonfiguration.
Kontrollera för nätverks-DTC-åtkomst och Tillåt utgående.
Klicka på OKoch klicka sedan på Ja för att starta om MSDTC-tjänsten.
Klicka på OK för att stänga dialogrutan.