Transactions


If you go to a bank and transfer $100 from your savings account to your checking account, you are engaging in a transaction. There are two actions that need to occura withdrawal from your savings account and a deposit to your checking account.

If for some reason one of those actions were to succeed and the other were to fail, there would be a problem. If the transfer from the withdrawal from your savings account was successful, and the deposit failed, your $100 would disappear. This is not a desirable outcome for you.

If the withdrawal from your savings account failed, but the deposit to the checking account for that amount was successful, you would essentially have gained $100 in funds at the expense of the bank. Although this would possibly be a nice situation for you, this is a less-than-ideal situation for the bank.

For this transaction to reach a satisfactory conclusion for all parties involved, the activities need to complete as expected. If one of them fails, any changes that have occurred need to be "rolled back" to a state where they were before the transaction occurred.

Atomic, Consistent, Isolated, and Durable (ACID)

Transactions have four key characteristics. Transactions must be Atomic, Consistent, Isolated, and Durable (ACID). Definitions of each of these characteristics are listed in the text that follows.

Atomic

For a transaction to be atomic, either all the actions must be successfully committed, or any state that has been affected must be rolled back to values that existed prior to the actions occurring.

In our example, this would mean that the money would be successfully withdrawn from the savings account and deposited into the checking account, or the funds would remain as they were at the start of the transaction.

Consistent

Consistency guarantees a predictable transformation of state. In our example, the account being debited by $100 and $100 being deducted from the account is consistent with our expectation.

Isolated

Whereas atomic was defined essentially as an all-or-nothing application of the actions within a transaction, isolated ensures that the transaction, and the changes being made within it, are opaque to the outside world.

When the work and state changes made within the transaction are isolated, the world outside the transaction continues to work with a state that is valid.

Assume, in our example, that the accounts in question were joint accounts shared with a spouse. If John Smith was in the middle of making a fund transfer and Jane Smith was making a withdrawal from an ATM, both transactions would be invisible to the other. The transactions would become visible after they were committed (that is, after the transfer was completed or the funds were dispensed).

Durable

For a transaction to be durable, committed updates must survive failures.

In our example, this would mean that if a power outage occurred after the transaction had committed, when the power was restored the state changes resulting from the withdrawal and deposit must remain.

Transactions on Windows

As mentioned in Chapter 1, "PrerequisitesGenerics and Transactions," Version 2.0 of the .NET framework introduced new additions for transactional programming. The System.Transactions namespace was introduced, as were two transaction managers (the Lightweight Transaction Manager [LTM] and the OleTx Transaction Manager). These were added to provide .NET developers the ability to develop more agile and performant transactional applications.

The Lightweight Transaction Manager provides support for transactions that exist in a single app domain; that have at most one durable store, for example SQL Server; and that do not require writes to the Transaction Log. For those transactions that involve multiple durable stores or cross app domains, the OleTx Transaction Manager would be used.

Through the System.Transactions namespace, .NET removes the need for the developer to make an upfront determination of which of these transaction managers to choose. System.Transactions provides the capability to promote transactions as required. By default, all transactions will utilize the Lightweight Transaction Manager and then be promoted to use the OleTx Transaction Manager in scenarios in which multiple durable stores are part of the transaction, or the transaction crosses multiple app domains.

Transactions and transactional behavior can be specified either declaratively using attributes or explicitly in .NET code. Examples of both can be seen here:

[Transaction(TransactionOption.Required)] public class WireTransfer : ServicedComponent {     [AutoComplete]     public double Transfer(       int sourceAccountNbr,       int targetAccountNbr,       double amount);     {       ...     } } public double Transfer(    int sourceAccountNbr,    int targetAccountNbr,    double amount) {    TransactionOptions options = new TransactionOptions();    options.IsolationLevel = IsolationLevel.ReadCommitted;    using (TransactionScope scope = new TransactionScope(        TransactionScopeOption.Required,        options))    {        //Code that will be part of the transaction    } }


WS-Atomic Transaction

As with security and reliability, the industry grew tired of patchwork solutions that were only relatively interoperable and went to work on standards in the area of transactions as well.

The most implemented of these standards is WS-Atomic Transaction (WS-AT). WS-AT defines a specific set of protocols for implementing two-phase atomic transactions.

WS-AT allows you to leverage existing software investments when moving toward a service-oriented enterprise. WS-AT incorporates transactions at the message level, providing the capability to implement all-or-nothing transactions with closely coupled systems that may span platforms.

Transaction Support in WCF

WCF provides the capability to flow transactions from a client to a service. In a Windows-only environment, WCF provides the capability to use the transactional capability inherent in .NET and the Windows platform. For cross-platform scenarios, it provides the capability to utilize WS-Atomic Transactions.

Note

WCF provides an implementation of WS-AT that is built into the Microsoft Distributed Transaction Coordinator (MSDTC). It supports authentication using Windows identities, and, for cross-platform interoperability, authentication using certificates. For the latter case, a trusted certificate must be installed into the machine's certificate store, and communication must be via HTTPS with client certificate authentication.


WCF uses policy assertions to control transaction flow. These assertions can be found in the service's policy document, which clients can access using HTTP GET or WS-MEX. With the document, clients and/or tools can determine how to interact with a service.

The assertions within the document are the result of a combination of information specified in attributes, contracts, and the configuration file.

TRansactionFlow Attribute

With the transactionFlow attribute, WCF provides the capability to associate transaction flow assertions with a specific operation.

Through this attribute, you can specify whether individual operations may support transactions (Allowed), must require transactions (Mandatory), or do not allow transactions (NotAllowed):

[TransactionFlow(TransactionFlowOption.Mandatory)]        bool PayBill(int account, decimal amount);


The enumeration transactionFlowOption is used for this, and the default value is NotAllowed.

Note

If the attribute is defined to either allow or require a transaction flow, the affected operations are required not to be specified as one-way.


Specifying Transactional Behaviors

Behaviors provide a way to declaratively specify how the service should behave, in this case in respect to transactions. Here you can specify whether an operation auto-completes on successful execution, and specify whether a transaction scope is required:

[ServiceContract]     public interface IElectricBillPay     {         [OperationContract]         [OperationBehavior(TransactionAutoComplete=true, TransactionScopeRequired=true)]         bool PayBill(int account, decimal amount);         [OperationContract]         decimal GetBalance(int account); }


Specifying the Transaction Protocol in Configuration

The protocol to use for transaction flow is specified in the configuration file. WCF provides three protocol options: OleTx, Wsat, or TxNego.

As you might imagine based on the text from earlier in the chapter, OleTx would be used for transactions that will occur only on the Microsoft platform, whereas Wsat is for support of transactions across platforms using WS-Atomic transactions. The third option, TxNego, actually provides the capability to let the service expose both. Reading the resulting policy file, services could determine the protocol they want to support.

As is noted in the documentation, the choice of protocol influences two separate factors:

  • The format of the SOAP headers used to flow the transaction from client to server

  • The protocol used between the client's transaction manager and the server's transaction to resolve the outcome of the transaction

Transaction Protocol for Preconfigured Bindings

For the out-of-the-box bindings provided with WCF, some default to OleTx protocol, whereas others default to WS-AT. The choice of transaction protocol within a binding can also be influenced programmatically.

Table 5.3. Default Support for Transactions in WCF's Preconfigured Bindings

Binding

Transaction Support

Default Protocol

BasicHttpBinding

No

N/A

WSHttpBinding

Yes

WS-AT

WSDualHttpBinding

Yes

WS-AT

WSFederationBinding

Yes

WS-AT

NetTcpBinding

Yes

OleTx

NetNamedPipeBinding

Yes

OleTx

NetMsmqBinding

Yes

OleTx

NetPeerTcpBinding

No

N/A

MsmqIntegrationBinding

Yes

OleTx


When creating the configuration file for services that use one of the preconfigured bindings, within the bindings section, you will add the TRansactionFlow attribute to the binding element and provide the value TRue:

<system.serviceModel>     <services>       <service           type="GenericElectricCompany.ElectricBillPay"     >       <!-- use base address provided by host -->       <endpoint address=""                 binding="wsHttpBinding"                 bindingConfiguration="transactionBinding"                 contract="GenericElectricCompany.IElectricBillPay"/>     </service> </services> <bindings>   <wsHttpBinding>     <binding name="transactionBinding" transactionFlow="true" />   </wsHttpBinding>    </bindings> </system.serviceModel>


In many cases, only one protocol is supported; in that case the TRansactionFlow attribute is all that is required. In the case of several bindings, such as the netTcpBinding and the netNamedPipeBinding, a specific protocol can be specified. Here, you would add the transactionProtocol attribute and identify the preferred protocol, OleTx, Wsat, or TxNego:

<bindings>       <netTcpBinding>           <binding name="test"                 closeTimeout="00:00:10"                 openTimeout="00:00:20"                 receiveTimeout="00:00:30"                 sendTimeout="00:00:40"                 transactionFlow="true"                 transactionProtocol="TxNego"                 hostNameComparisonMode="WeakWildcard"                 maxBufferSize="1001"                 maxConnections="123"                 maxMessageSize="1000"                 portSharingEnabled="true">                 <reliableSession ordered="false"                     inactivityTimeout="00:02:00"                     enabled="true" />                 <security mode="Message">                     <message clientCredentialType="Windows" />                 </security>             </binding>         </netTcpBinding>     </bindings> </system.ServiceModel>


Transaction Protocol for Custom Bindings

When developing your own custom bindings, you will create a transactionFlow element for the binding and specify the transaction protocol using the transactionProtocol attribute:

<customBinding>         <binding name="WCFHandsOnTxBinding">             <transactionFlow transactionProtocol="Wsat"/>         </binding>       </customBinding>


Enabling WS-Atomic Transactions

WS-Atomic Transaction support is not turned on by default. The xws_reg.exe utility can be used to turn on WS-AT support from the command line.

Open the Visual Studio command prompt (select Start, All Programs, Microsoft Visual Studio 2005, Visual Studio Tools, Visual Studio command prompt).

Execute the utility with the following command-line parameter:

xws_reg v wsat+






Presenting Microsoft Communication Foundation. Hands-on.
Microsoft Windows Communication Foundation: Hands-on
ISBN: 0672328771
EAN: 2147483647
Year: 2006
Pages: 132

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net