Windows Communication Foundation (WCF) アプリケーションは、クライアント内からトランザクションを開始し、サービス操作内でトランザクションを調整できます。 クライアントは、トランザクションを開始し、複数のサービス操作を呼び出し、サービス操作が 1 つのユニットとしてコミットまたはロールバックされるようにすることができます。
サービス コントラクトでトランザクション動作を有効にするには、 ServiceBehaviorAttribute を指定し、クライアント トランザクションを必要とするサービス操作の TransactionIsolationLevel プロパティと TransactionScopeRequired プロパティを設定します。 TransactionAutoComplete パラメーターは、未処理の例外がスローされなかった場合に、メソッドが実行されているトランザクションが自動的に完了されるかどうかを指定します。 これらの属性の詳細については、「 ServiceModel トランザクション属性」を参照してください。
サービス操作で実行され、データベース更新のログ記録などのリソース マネージャーによって管理される作業は、クライアントのトランザクションの一部です。
次の例では、 ServiceBehaviorAttribute 属性と OperationBehaviorAttribute 属性を使用してサービス側のトランザクション動作を制御する方法を示します。
[ServiceBehavior(TransactionIsolationLevel = System.Transactions.IsolationLevel.Serializable)]
public class CalculatorService: ICalculatorLog
{
[OperationBehavior(TransactionScopeRequired = true,
TransactionAutoComplete = true)]
public double Add(double n1, double n2)
{
recordToLog($"Added {n1} to {n2}");
return n1 + n2;
}
[OperationBehavior(TransactionScopeRequired = true,
TransactionAutoComplete = true)]
public double Subtract(double n1, double n2)
{
recordToLog($"Subtracted {n1} from {n2}");
return n1 - n2;
}
[OperationBehavior(TransactionScopeRequired = true,
TransactionAutoComplete = true)]
public double Multiply(double n1, double n2)
{
recordToLog($"Multiplied {n1} by {n2}");
return n1 * n2;
}
[OperationBehavior(TransactionScopeRequired = true,
TransactionAutoComplete = true)]
public double Divide(double n1, double n2)
{
recordToLog($"Divided {n1} by {n2}", n1, n2);
return n1 / n2;
}
}
トランザクションとトランザクション フローを有効にするには、WS-AtomicTransaction プロトコルを使用するようにクライアント バインドとサービス バインドを構成し、次のサンプル構成に示すように <transactionFlow> 要素を true
に設定します。
<client>
<endpoint address="net.tcp://localhost/ServiceModelSamples/service"
binding="netTcpBinding"
bindingConfiguration="netTcpBindingWSAT"
contract="Microsoft.ServiceModel.Samples.ICalculatorLog" />
</client>
<bindings>
<netTcpBinding>
<binding name="netTcpBindingWSAT"
transactionFlow="true"
transactionProtocol="WSAtomicTransactionOctober2004" />
</netTcpBinding>
</bindings>
クライアントは、トランザクションを開始するには、 TransactionScope を作成し、トランザクションのスコープ内でサービス操作を呼び出します。
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew))
{
//Do work here
ts.Complete();
}