Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
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žena na ukázce Začínáme, která implementuje službu kalkulačky, ale je rozšířena tak, aby uchovávala protokol operací serveru v databázové tabulce a stavový běžící 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 transakcí, je služba nakonfigurována pomocí wsHttpBinding poskytnutého systémem, přičemž atribut transactionFlow je nastaven 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
TransactionTimeouturčuje časové období, během kterého se transakce musí dokončit. V této ukázce je nastavená na 30 sekund.Vlastnost
TransactionIsolationLevelurčuje úroveň izolace, kterou služba podporuje. To se vyžaduje, aby odpovídalo úrovni izolace klienta.Vlastnost
ReleaseServiceInstanceOnTransactionCompleteurč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
TransactionAutoCompleteOnSessionCloseurčuje, zda se při zavření relace dokončí nevyřízené transakce. Nastavením nafalsejsou jednotlivé operace povinny buď nastavit OperationBehaviorAttribute.TransactionAutoComplete vlastnost natruenebo výslovně vyžadovat volání metody OperationContext.SetTransactionComplete() k dokončení transakcí. Tato ukázka ukazuje oba přístupy.
Na :
ServiceContractAttribute- Vlastnost
SessionModeurčuje, zda služba koreluje příslušné požadavky do logické relace. Vzhledem k tomu, že tato služba obsahuje operace, kde je vlastnost OperationBehaviorAttribute TransactionAutoComplete nastavena na hodnotufalse(Násobení a Dělení), je nutné zadatSessionMode.Required. Například operace násobení nedokončí svou transakci a místo toho se spoléhá na pozdější volání operace dělení k dokončení pomocí metodySetTransactionComplete; služba proto musí být schopna určit, že tyto operace probíhají ve stejné relaci.
- Vlastnost
Na
OperationBehaviorAttribute:Vlastnost
TransactionScopeRequiredurčuje, zda se mají provádět akce operace v rámci oboru transakce. Je nastaveno natruepro všechny operace v této ukázce a protože klient přenáší svou transakci ke všem operacím, akce se provádějí v rámci této klientské transakce.Vlastnost
TransactionAutoCompleteurč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á protrueoperace sčítání a odčítání, alefalsepro operace násobení a dělení. Operace sčítání a odečítání dokončují své akce automaticky, funkce Divide dokončuje své akce explicitním voláním metodySetTransactionComplete, a funkce Multiply nedokončuje své akce, ale spoléhá na pozdější volání, například na Divide, k dokončení akcí.
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 operace služby je zobrazeno v konzole 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 souvisejí s transakcí klienta, jakékoliv selhání při 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í klienta
tx.Complete() a spusťte jej znovu – to způsobí ukončení transakčního oboru bez jejího dokončení.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 kterékoli z těchto operací je, že žádné operace provedené v daném oboru se nezapíší a počet řádků, které jsou v databázi trvale uložené, se nezvyšuje.
Poznámka:
V rámci procesu sestavení se soubor databáze zkopíruje do složky bin. Pokud chcete sledovat ukládání řádků do protokolu, místo na soubor, který je součástí projektu ve Visual Studiu, musíte se podívat na kopii tohoto souboru databáze.
Nastavte, sestavte a spusťte ukázku
Ujistěte se, že jste nainstalovali SQL Server 2005 Express Edition nebo SQL Server 2005. V souboru App.config služby je možné nastavit databázi
connectionStringnebo lze zakázat interakce s databází tak, že nastavíte hodnotu appSettingsusingSqlnafalse.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 jedno- nebo vícepočítačové konfiguraci, postupujte podle pokynů v Spuštění ukázek Windows Communication Foundation.
Pokud spustíte ukázku na různých počítačích, musíte nakonfigurovat Microsoft Distributed Transaction Coordinator (MSDTC) pro povolení toku síťových transakcí a pomocí nástroje WsatConfig.exe povolit síťovou podporu 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 klikněte na 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.