Apply TransactionFlowAttribute
on the contract, not the service class.
Do not perform transactional work in the service constructor.
Using this book’s terminology, configure services for either Client or Client/Service transactions. Avoid None or Service transactions.
Using this book’s terminology, configure callbacks for either Service or Service/Callbacks transactions. Avoid None or Callback transactions.
When using the Client/Service or the Service/Callback modes, constrain the binding to flow transaction using the BindingRequirement
attribute.
On the client, always catch all exceptions thrown by a service configured for None or Service transactions.
Strive to always configure operations to at least allow transactions:
[ServiceContract] interface IMyContract { [OperationContract] [TransactionFlow(TransactionFlowOption.Allowed)] void MyMethod1(...); }
Enable reliability and ordered delivery even when using transactions.
In a service operation, never catch an exception and manually abort the transaction:
//Avoid:
[OperationBehavior(TransactionScopeRequired = true)]
public void MyMethod( )
{
try
{
...
}
catch
{
Transaction.Current.Rollback
( );
}
}
If you catch an exception in a transactional operation, always rethrow it or another exception.
Always use the default isolation level of IsolationLevel.Serializable
.
Do not call one-way operations from within a transaction.
Do not call nontransactional services from within a transaction.
Do not access nontransactional resources (such as the filesystem) from within a transaction.
Avoid transactional sessionful services.
Prefer per-call transactional services.
When using a sessionful or transactional singleton, use volatile resource managers to manage state and avoid explicitly state-aware programming or relying on the WCF instance deactivation on completion.