ドメイン駆動開発_フォルダー構成編_#57_トランザクションはどこでかける?

当サイトではアフィリエイト広告を利用しています。

NDDD

今回はトランザクションをどこでかけるべきか?というお話をします。

データベースを使っていると,トランザクションをかける必要が出てきます。例えば受注ヘッダーと受注明細テーブルを登録する場合はトランザクションをかけて,データの不整合が起きないようする必要があります。

トランザクションはどこでかけるべきか?

今回のプロジェクト構成であれば,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();
            }
        }

これだけで成功したらコミット,失敗したらロールバックされます。このようにして,すべて使う側でトランザクションをかければ,使いたい人の自由にかけられるので,柔軟に対応することができます。