SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

実例で学ぶASP.NET Webフォーム業務アプリケーション開発のポイント

データの整合性を確保するためのトランザクション制御

実例で学ぶASP.NET Webフォーム業務アプリケーション開発のポイント 第5回

  • X ポスト
  • このエントリーをはてなブックマークに追加

トランザクション制御を行う際のポイント

 トランザクション制御の実装方法まで分かったところで、実際にトランザクション制御を行う際のポイントをいくつか紹介します。

ポイント1:トランザクション制御はビジネスロジック層で行う

 トランザクション制御は、プレゼンテーション層でもデータアクセス層でもなく、ビジネスロジック層で行うようにします。リスト2で掲載したコードもビジネスロジック層のものです。

 これは、トランザクション制御の方針がビジネスロジックの要件に左右されるためです。

 仮にデータアクセス層でトランザクション制御を行ってしまうと、複数のテーブルに対しての処理を1つのトランザクションにまとめることができなくなってしまいます。また、1つのトランザクションにしようと1つのデータアクセス層処理で複数のテーブルを更新してしまっては、それはすでにデータアクセスではなくビジネスロジックの役割を与えられていることになるので、これはその処理をビジネスロジック層に移動させるべきです。

図6 トランザクション制御対象のイメージ
図6 トランザクション制御対象のイメージ

ポイント2:可能ならビジネスロジック層の処理の全体をトランザクション制御対象とする

 ビジネスロジック層に更新処理メソッドがあった場合、更新処理メソッドの最初でトランザクションを開始し、最後にトランザクションをコミット/ロールバックするようにすべきです。

リスト4 MRRL.BLL.ReservationLogicクラス、Updateメソッド
/// <summary>
/// 予約情報を更新します。
/// </summary>
/// <param name="reservation"></param>
public void Update(Reservation reservation)
{
  using (var ts = new TransactionScope())
  {
    if (OverlapsOtherReservation(reservation))
    {
      // 重複した予約あり
      throw new OverlapReservationException();
    }

    _reservationRepository.Update(reservation);
    _reservationRepository.Save();

    ts.Complete();
  }
}

 これは次のように、中途半端にトランザクションの範囲を絞ることで、トランザクションに参加しないデータアクセスが発生することを防ぐためです。そのデータアクセスが参照系だけならそれほど影響はありませんが、更新系処理をうっかりトランザクションに参加させなかった場合、本記事冒頭の「トランザクション制御なし」と同じように、その更新処理だけ独立して確定されてしまいます。

リスト5 TransactionScopeに参加しないデータアクセス発生の例
public void Update(Reservation reservation)
{
  if (OverlapsOtherReservation(reservation))
  {
    // 重複した予約あり
    throw new OverlapReservationException();
  }

  using (var ts = new TransactionScope())
  {
    _reservationRepository.Update(reservation);
    _reservationRepository.Save();

    ts.Complete();
  }
}

 なお、ビジネスロジックの要件として複数のトランザクションを制御しなければならないような場合はこの限りではありません。ただ、可能な限りトランザクションのスコープは広くとるべきです。そのためにも、次のようにトランザクションの単位でメソッドアウトすることをお勧めします。

リスト6 複数トランザクションが必要なビジネスロジックの例
public void UpdateTables(ComplexData data)  // (1)
{
  UpdateTable1(data.Table1Entity);
  UpdateTable2(data.Table2Entity);
}

private void UpdateTable1(Table1Entity entity)  // (2)
{
  using (var ts = new TransactionScope())
  {
    // Table1更新処理

    ts.Complete();
  }
}

private void UpdateTable2(Table2Entity entity)
{
  using (var ts = new TransactionScope())
  {
    // Table2更新処理

    ts.Complete();
  }
}

 (1)更新処理メインロジックのメソッドでは、各トランザクション管理対象毎のメソッドを呼ぶようにする。

 (2)トランザクション制御対象処理ごとにprivateなメソッドとしてメソッドアウトする。このメソッドでは内部の処理すべてをTransactionScopeのusingブロックで囲みます。

まとめ

 データの整合性を保つためのトランザクション制御のポイントは、以下のとおりです。

  • データを更新する際の一連の処理の塊を「トランザクション」という。
  • トランザクション制御とは、一連の処理の開始、確定(コミット)、取消(ロールバック)を制御することをいう。
  • トランザクション制御には大きく分けて2つのタイプがある。
    • 明示的トランザクション制御
      バッチ処理などでよく使われる。分散トランザクションには対応していない。
      自分でトランザクションの開始、確定、取消をすべて制御する方法。
    • 暗黙的トランザクション制御
      現在の主流のトランザクション制御方法。
      分散トランザクションに対応している上、構文がシンプルになる。
  • トランザクション制御の実装は次のように行う。
    • 明示的トランザクション制御
      IDbConnection.BeginTransactionメソッドでトランザクションを開始し、IDbTransaction.Commit/Rollbackメソッドで終了させる。
    • 暗黙的トランザクション制御
      System.Transaction.TransactionScope型をusingブロックともに使用し、コミットしてよい場合、usingブロックの最後でTransactionScope.Completeメソッドを呼び出す。
  • トランザクション制御のポイントは次の2つ。
    • ポイント1:トランザクション制御はビジネスロジック層で行う。
    • ポイント2:トランザクション制御対象処理ごとにメソッドを作成し、極力メソッドの内部すべてを1つのトランザクション制御範囲とする。

 さて、次回はデータの整合性を保つために必要なもう一つの要素、排他制御について紹介する予定です。次回もお楽しみに。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
実例で学ぶASP.NET Webフォーム業務アプリケーション開発のポイント連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 高野 将(タカノ ショウ)

<個人紹介>新潟県長岡市在住の在宅リモートワークプログラマー。家事や育児、仕事の合間に長岡IT開発者勉強会(NDS)、Niigata.NET、TDDBCなどのコミュニティに関わったり、Web記事や書籍などの執筆を行ったりしている。著書に『アプリを作ろう! Visual C#入門 Visual C# 2017対応』(日経BP社、2017)など。<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/6702 2012/08/07 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング