今回はトランザクションをどこでかけるべきか?というお話をします。
データベースを使っていると,トランザクションをかける必要が出てきます。例えば受注ヘッダーと受注明細テーブルを登録する場合はトランザクションをかけて,データの不整合が起きないようする必要があります。
トランザクションはどこでかけるべきか?
今回のプロジェクト構成であれば,SQLServerにアクセスするのはInfrastructure層なので,Infrastructure層でトランザクションをかけるべきなのか?と考えるかもしれませんが,結果的にはViewModelでかけるのがいいです。要するに,使う側,クライアントコード側でかけます。
Infrastructure層でトランザクションをかけないほうがいい理由
Infrastructure層でトランザクションをかけると,融通が利かなくなります。OrderSqlServerクラスで発注テーブルと発注明細テーブルを登録し,そこでトランザクションをかけてしまうと,その後で在庫の更新や,発注履歴テーブルの更新をしたいケースでは,2重でトランザクションをかけることになり,うまく動作しません。要するに,使う人の好きなようにさせておいてあげないと,融通が利かないコードになります。
トランザクションのかけ方
WinFormプロジェクトに参照の追加
検索窓にtransaと入力し,System.TransactionsにチェックをいれてOKボタンを押下して,参照を追加します。
ViewModelへの実装
ViewModelなどのクライアントコードで次のように実装して,トランザクションをかけます。次の例ではSave処理の中で複数のテーブル更新がある場合に,TransactionScopeを生成し,usingでトランザクション範囲を囲みます。処理の最後でCompleteを呼び出します。
public void Save() { using (var scope = new TransactionScope()) { //ヘッダー //明細 //在庫 //履歴 //顧客情報 scope.Complete(); } }
これだけで成功したらコミット,失敗したらロールバックされます。このようにして,すべて使う側でトランザクションをかければ,使いたい人の自由にかけられるので,柔軟に対応することができます。