LoginSignup
22
1

More than 1 year has passed since last update.

UnitOfWork

Last updated at Posted at 2022-12-05

export 6.png

ここからは「オブジェクトリレーショナル振る舞いパターン」に属すパターンの紹介です。

Unit Of Work パターンは、Domain Model 内で起こるさまざまな変更を、都度データベースに随時反映させず、一連のビジネスロジックが完了した後に、Domain Model の外で最終的な結果をまとめて反映させる方式を指します。

いくつもの構成要素が連携する Domain Model パターンでは、互いに他のオブジェクトのロジックがどうなっているかの詳細には踏み込みません。責務を満たすなら詳細を問わないのが、オブジェクト指向を活かしたモデリングです。が、もし連携するビジネスロジックが SQL を発行していると、それは思わぬパフォーマンス問題につながるかもしれません。

別のオブジェクトにある「ひとつ処理する」のメソッドが便利だからと、軽い気持ちで 10 回呼び出してしまうと、場合によっては 10 倍のクエリが実行されることになります。そんな下手なプログラミングをする方が悪いのだと、中にどんな SQL が書かれているかを把握しに行こうとすると、それは実質的に、プログラムを Transaction Script として読解しようとしているのと同じです。

データベーストランザクション中に、時間のかかる別の通信を行っているオブジェクトを使う可能性もあります。長時間トランザクションが並行して数多く存在すると、デッドロックが起きる確率が高まります。そうでなくても、トランザクション分離を同時に数多く抱えることは、データベースにとってたいへんな負荷になります。

Unit Of Work を意識した Data Mapper は、データを表すオブジェクトの変更を監視し、ビジネスロジックの終了後に、その監視対象から差分情報を生成します。差分情報をもとに、最小の更新用 SQL を発行して、Domain Model での変化とデータベースを同期します。これにより、Domain Model 内の処理の詳細を知らなくても、ベストなパフォーマンスを得ることができます。また、データ同期のためのデータベーストランザクション時間が、とても短くなります。

トランザクションの ACID 性と、複数の並行処理がデータの矛盾を発生させないようにするロックとは、別の問題です。並行処理のロックについては、別のパターンで述べられています。

Unit Of Work と Active Record は、完全に排他的な関係です。Active Record のデータ更新はどうしても、自身を Row Data Gateway として使った即時 SQL 発行になります。Active Record パターンの手軽さを保留した別の工夫を考えなければ、Unit Of Work はできません。逆に Data Mapper は、ごく自然に Unit Of Work と共存します。Active Record と Data Mapper の違いのうち、メカニズム上の最大の差がこの点です。

22
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
1