Wcf-transaction
WCF-トランザクション
WCFのトランザクションは、ACIDと総称されるいくつかのプロパティに従う一連の操作です。 ここで、1つの操作が失敗すると、システム全体が自動的に失敗します。 注文がオンラインになると、トランザクションが発生します。 次の例は、トランザクションのプロセスをより簡単に理解するのに役立ちます。
例
オンラインストアで液晶テレビを注文し、クレジットカードで金額を支払うとします。 注文するために必要な情報を入力すると、2つの操作が同時に発生します。
1つ目は、指定された金額が銀行口座から引き落とされ、2つ目はベンダー口座に同じ金額が入金されることです。 トランザクションを成功させるには、両方の操作を正常に実行する必要があります。
WCFトランザクションプロパティ
WCFトランザクションが続く4つのプロパティは次のとおりです-
- アトミック-すべての操作は、トランザクションの完了時に単一の分割できない操作として機能する必要があります。
- 一貫性-操作セットが何であっても、システムは常に一貫性のある状態にあります。つまり、トランザクションの結果は常に期待どおりです。
- 分離-システムの中間状態は、トランザクションが完了するまで外界のどのエンティティにも見えません。
- 耐久性-障害の種類(ハードウェア、停電など)に関係なく、コミットされた状態が維持されます。
WCFトランザクションを構成する際には、考慮が必要ないくつかの要因があります。 これらはバインディングと操作の動作です。
バインディング-WCFでトランザクションをサポートするバインディングは少数であり、デフォルトで無効になっているこれらのバインディングのみから選択することが重要です。 これらのバインディングは次のとおりです-
- NetTcpBinding
- NetNamedPipeBinding
- WSHttpBinding
- WSDualHttpBinding
- WSFederationHttpBinding
操作の動作-バインディングはトランザクションの伝播のパスを容易にしますが、操作はトランザクションの処理と操作の構成を処理します。 操作の動作では、主にTransactionFlowとTransactionScopeRequiredの2つの属性を使用します。 ここで、TransactionFlowには主に3つの値があり、これらはAllowed、Mandatory、NotAllowedであることに注意してください。
次のコードは、バインディングおよび操作コントラクトの構成を変更すると、クライアントの伝播が促進されるかどうかを示しています。
<bindings>
<wsHttpBinding>
<binding name = "MandatoryTransBinding" transactionFlow = "true">
<reliableSession enabled ="true"/>
</binding>
</wsHttpBinding>
</bindings>
トランザクションプロトコル
WCFは、トランザクションに3種類のプロトコルを使用します-
- 軽量
- オレ取引
- WS-Atomic Transaction(WS-AT)
3つすべてのうち、WS-ATは相互運用可能なプロトコルであり、ファイアウォールを越えた分散トランザクションのフローを可能にします。 ただし、トランザクションがMicrosoftテクノロジーに厳密に基づいている場合は、このプロトコルを使用しないでください。
WCFトランザクションのフェーズ
次の図に示すように、WCFトランザクションには2つのフェーズがあります。
- 準備フェーズ-このフェーズでは、トランザクションマネージャは、すべてのエンティティがトランザクションにコミットする準備ができているかどうかをチェックします。
- コミットフェーズ-このフェーズでは、エンティティのコミットメントが実際に開始されます。
次の図は、WCFトランザクションの両方のフェーズの機能を示しています。
WCFトランザクションを有効にする
WCFトランザクションを正常に有効にするには、一連の6つの手順を順番に実行する必要があります。 必要な手順を以下に説明します。
ステップ1-2つのWCFサービスの作成
これに関する最初のステップは、単一のトランザクションに参加するために、WCFで2つのサービスプロジェクトを構築することです。 データベーストランザクションはこれらの両方のサービスで実行され、WCFトランザクションによってどのように統合されるかが理解されます。 WCFTransactionsのWebアプリケーションも作成され、単一のトランザクションスコープで作成された2つのサービスを使用します。
ステップ2-メソッドの作成とTransactionFlow属性によるその属性
ここでは、OperationContract属性を使用してデータベースに挿入するために、両方のWCFサービスに対してUpdateDataメソッドが作成されます。 このタスクを実行するには、最初にServiceContract属性を使用してインターフェイスクラスを作成します。 新しく作成されたメソッドでトランザクションを有効にするには、TransactionFlowに関連付けられ、Allowed値を使用してトランザクションが許可されます。
[ServiceContract]
public interface IService1 {
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
void UpdateData();
}
ステップ3-TransactionScopeRequired属性を使用したWCFサービスの実装
それは以下に示すコードを使用して行われます-
[OperationBehavior(TransactionScopeRequired = true)]
public void UpdateData() {
try {
SqlConnection objConnection = new SqlConnection(strConnection);
objConnection.Open();
using(SqlTransaction transaction = Program.dbConnection.BeginTransaction()) {
Boolean doRollback = false;
using(SqlCommand cmd = new SqlCommand(
"insert into Customer (Customer name, Customer code) values ('sss', 'sss')"objConnection))
try {
cmd.ExecuteNonQuery();
} catch(SqlException) {
doRollback = true;
break;
}
}
if(doRollback)
transaction.Rollback();
else
transaction.Commit();
}
finally {
objConection.Close();
}
}
ステップ4-WCFサービス構成ファイルによるトランザクションフローの有効化
そのコーディングは次のように行われます-
<bindings>
<wsHttpBinding>
<binding name = "TransactionalBind" transactionFlow = "true"/>
</wsHttpBinding>
</bindings>
WCFサービスを公開するには、トランザクション許容バインディングをエンドポイントにアタッチすることが重要です。
<endpoint address = "" binding = "wsHttpBinding" bindingConfiguration = "TransactionalBind" contract = "WcfService1.IService1">
ステップ5-単一のトランザクションで両方のサービスを呼び出す
ここでは、上記の2つのサービスが1つのトランザクションで呼び出され、この目的のために、TransactionScopeオブジェクトを使用して両方のサービスをグループ化します。 上記のオブジェクトのCompleteメソッドは、WCFトランザクションをコミットするために呼び出されます。 ロールバックするには、Disposeメソッドを呼び出します。
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew)) {
try {
//Call your webservice transactions here
ts.Complete();
} catch (Exception ex) {
ts.Dispose();
}
}
WCFトランザクションが1つのスコープにグループ化されている完全なコードの小さな部分を以下に示します-
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew)) {
try {
ServiceReference1.Service1Client obj = newServiceReference1.Service1Client();
obj.UpdateData();
ServiceReference2.Service1Client obj1 = new ServiceReference2.Service1Client();
obj1.UpdateData();
ts.Complete();
} catch (Exception ex) {
ts.Dispose();
}
}
ステップ6-WCFトランザクションのテスト
テストは6番目の最終ステップで行われ、最初のWCFサービスを呼び出した後、例外が強制されます。