Chování transakce služby
Ukázka transakcí ukazuje použití transakce koordinované klientem a nastavení ServiceBehaviorAttribute a OperationBehaviorAttribute k řízení chování transakce služby. Tato ukázka je založená na ukázce Začínáme, která implementuje službu kalkulačky, ale je rozšířena, aby se zachoval protokol serveru provedených operací v tabulce databáze a stavový průběžný součet pro operace kalkulačky. Trvalé zápisy do tabulky protokolu serveru jsou závislé na výsledku koordinované transakce klienta – pokud klient transakce nedokončí, transakce webové služby zajistí, že aktualizace databáze nebudou potvrzeny.
Poznámka:
Postup nastavení a pokyny k sestavení pro tuto ukázku najdete na konci tohoto článku.
Kontrakt služby definuje, že všechny operace vyžadují tok transakce s požadavky:
[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);
}
Chcete-li povolit příchozí tok transakce, služba je nakonfigurována se systémem zadaný wsHttpBinding s atributem transactionFlow nastaveným na true
. Tato vazba používá interoperabilní protokol WSAtomicTransactionOctober2004:
<bindings>
<wsHttpBinding>
<binding name="transactionalBinding" transactionFlow="true" />
</wsHttpBinding>
</bindings>
Po zahájení připojení ke službě i transakci klient přistupuje k několika operacím služby v rámci této transakce a pak dokončí transakci a ukončí připojení:
// 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();
Ve službě existují tři atributy, které ovlivňují chování transakce služby, a to následujícími způsoby:
Na :
ServiceBehaviorAttribute
Vlastnost
TransactionTimeout
určuje časové období, během kterého se transakce musí dokončit. V této ukázce je nastavená na 30 sekund.Vlastnost
TransactionIsolationLevel
určuje úroveň izolace, kterou služba podporuje. To se vyžaduje, aby odpovídalo úrovni izolace klienta.Vlastnost
ReleaseServiceInstanceOnTransactionComplete
určuje, zda je instance služby recyklována po dokončení transakce. Když ji nastavíte nafalse
, služba udržuje stejnou instanci služby napříč požadavky na operace. To je nutné k udržení průběžného součtu. Pokud je nastavená hodnotatrue
, po každé dokončené akci se vygeneruje nová instance.Vlastnost
TransactionAutoCompleteOnSessionClose
určuje, zda se při zavření relace dokončí nevyřízené transakce. Nastavením nafalse
, jednotlivé operace jsou vyžadovány buď nastavit OperationBehaviorAttribute.TransactionAutoComplete vlastnost natrue
nebo explicitně vyžadovat volání OperationContext.SetTransactionComplete() metody k dokončení transakcí. Tato ukázka ukazuje oba přístupy.
Na :
ServiceContractAttribute
- Vlastnost
SessionMode
určuje, zda služba koreluje příslušné požadavky do logické relace. Vzhledem k tomu, že tato služba obsahuje operace, kde OperationBehaviorAttribute TransactionAutoComplete vlastnost je nastavena nafalse
hodnotu (Multipli and Divide),SessionMode.Required
musí být zadána. Například operace Násobení nedokončí svou transakci a místo toho spoléhá na pozdější volání funkce Divide k dokončení pomocíSetTransactionComplete
metody; služba musí být schopna určit, že k těmto operacím dochází ve stejné relaci.
- Vlastnost
Na :
OperationBehaviorAttribute
Vlastnost
TransactionScopeRequired
určuje, zda se mají provádět akce operace v rámci oboru transakce. Toto nastavení je nastaveno protrue
všechny operace v této ukázce a vzhledem k tomu, že klient tokuje svou transakci do všech operací, dojde k akcím v rámci této klientské transakce.Vlastnost
TransactionAutoComplete
určuje, zda transakce, ve které se metoda spouští, je automaticky dokončena, pokud nedojde k neošetřeným výjimkám. Jak jsme už popsali dříve, je tato možnost nastavená protrue
operace sčítání a odčítání, alefalse
pro operace násobení a dělení. Operace sčítání a odečítání dokončí své akce automaticky, funkce Divide dokončí své akce explicitním volánímSetTransactionComplete
metody a funkce Multipli nedokončí své akce, ale k dokončení akcí se spoléhá a vyžaduje pozdější volání, například dělit.
Implementace služby s atributem je následující:
[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 omitted for brevity
}
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
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.
Protokolování žádostí o operaci služby se zobrazí v okně konzoly služby. Stisknutím klávesy ENTER v okně klienta klienta ukončete klienta.
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
Všimněte si, že kromě zachování průběžného součtu výpočtů služba hlásí vytváření instancí (jednu instanci pro tuto ukázku) a protokoluje požadavky operací do databáze. Vzhledem k tomu, že všechny požadavky tok transakce klienta, všechny selhání dokončení této transakce způsobí vrácení všech databázových operací zpět. To lze demonstrovat mnoha způsoby:
Zakomentujte volání
tx.Complete
klienta () a spusťte ho znovu – výsledkem je ukončení oboru transakce bez dokončení transakce.Zakomentujte volání operace Dělení služby – tím zabráníte dokončení akce zahájené operací násobení, a proto se transakce klienta nakonec nezdaří dokončit.
Vyvolá neošetřenou výjimku kdekoli v oboru transakce klienta – to podobně zabrání klientovi v dokončení transakce.
Výsledkem některé z těchto operací je to, že se žádné operace provedené v daném oboru nezapíšou a počet řádků, které jsou v databázi trvalé, se nezvýšují.
Poznámka:
V rámci procesu sestavení se soubor databáze zkopíruje do složky přihrádky. Pokud chcete sledovat řádky, které jsou trvalé v protokolu, a ne na soubor, který je součástí projektu sady Visual Studio, musíte se podívat na tuto kopii souboru databáze.
Nastavení, sestavení a spuštění ukázky
Ujistěte se, že jste nainstalovali SQL Server 2005 Express Edition nebo SQL Server 2005. V souboru App.config služby může být databáze
connectionString
nastavena nebo interakce databáze mohou být zakázány nastavením hodnoty appSettingsusingSql
nafalse
hodnotu .Pokud chcete sestavit edici C# nebo Visual Basic .NET řešení, postupujte podle pokynů v části Sestavení ukázek windows Communication Foundation.
Pokud chcete spustit ukázku v konfiguraci s jedním nebo více počítači, postupujte podle pokynů v části Spuštění ukázek windows Communication Foundation.
Pokud spustíte ukázku na počítačích, musíte nakonfigurovat Microsoft Distributed Transaction Coordinator (MSDTC) povolit tok síťových transakcí a pomocí nástroje WsatConfig.exe povolit podporu sítě transakcí wcf (Windows Communication Foundation).
Konfigurace koordinátoru distribuovaných transakcí Microsoftu (MSDTC) pro podporu spuštění ukázky na počítačích
Na počítači služby nakonfigurujte MSDTC tak, aby povoloval příchozí síťové transakce.
V nabídce Start přejděte na Ovládací panely, pak nástroje pro správu a potom na Službu komponent.
Klikněte pravým tlačítkem myši na Můj počítač a vyberte Vlastnosti.
Na kartě MSDTC klepněte na tlačítko Konfigurace zabezpečení.
Zkontrolujte přístup DTC k síti a povolte příchozí provoz.
Klepnutím na tlačítko Ano restartujte službu MS DTC a klepněte na tlačítko OK.
Kliknutím na OK zavřete dialogové okno.
Na počítači služby a klientském počítači nakonfigurujte bránu Windows Firewall tak, aby zahrnovala službu Microsoft Distributed Transaction Coordinator (MSDTC) do seznamu s výjimkou aplikací:
Spusťte aplikaci brány Windows Firewall z Ovládací panely.
Na kartě Výjimky klepněte na tlačítko Přidat program.
Přejděte do složky C:\WINDOWS\System32.
Vyberte Msdtc.exe a klikněte na Otevřít.
Kliknutím na tlačítko OK zavřete dialogové okno Přidat program a dalším kliknutím na tlačítko OK zavřete aplet brány Windows Firewall.
Na klientském počítači nakonfigurujte MSDTC tak, aby umožňoval odchozí síťové transakce:
V nabídce Start přejděte na Ovládací panely, pak nástroje pro správu a potom na Službu komponent.
Klikněte pravým tlačítkem myši na Můj počítač a vyberte Vlastnosti.
Na kartě MSDTC klepněte na tlačítko Konfigurace zabezpečení.
Zkontrolujte přístup DTC k síti a povolte odchozí provoz.
Klepnutím na tlačítko Ano restartujte službu MS DTC a klepněte na tlačítko OK.
Kliknutím na OK zavřete dialogové okno.