[デザインパターン/トランザクション制御]

TRANSACTION CONTEXT

平澤 章
Ver 0.1 - 1999/8/23

1 目的

トランザクション処理に依存する情報、あるいはシステム全体で共通な情報を、オブジェクト間で暗黙的に共有する。

2 別名

CONTEXT HOLDER

3 動機

一般的にオブジェクト指向アプローチを採用することにより、アプリケーションは明確に役割を定義された粒度の小さいオブジェクトが協調動作するように設計される。

一方でトランザクション処理などにおいては、以下のようにある一連の処理のために多くのオブジェクト間で共有しておくべき情報が存在する。

このような情報をオブジェクト間のメッセージパッシングの引数として受け渡すと、引数の数が非常に多くなってしまう可能性がある。またあるオブジェクト自身の処理には関係がなくても、そのオブジェクトがさらに処理を依頼する別のオブジェクトで必要となる情報までをすべて明示的に受け渡すようにすると、共有情報に変更が発生した場合の影響範囲が大きくなってしまう。

したがって、このような共有情報はメッセージパッシングの引数として受け渡さずに、必要なオブジェクト同士で暗黙的に受け渡すことができるようにすべきである。

4 適用可能性

TRANSACTION CONTEXTパターンは、次のような場合に適用することができる。

5 構造

TransactionContext Class Diagram #1

6 構成要素

7 協調関係

省略

8 結果

8.1 メリット

  1. オブジェクト間のインタフェースがシンプルになる
    メッセージパッシングでやり取りされる引数情報が少なくなるため、オブジェクト間のインタフェースをシンプルにすることができる。

8.2 デメリット、留意点

  1. 不在参照が発生しないように注意すること
    情報が暗黙的に受け渡されることは、アプリケーションのバグなどによって設定されていない情報を参照しようとしてしまう不在参照が発生しやすくなることでもある。システムやトランザクションの初期化時点で設定し、後は参照するだけの情報ならばこのような問題は起きにくいが、途中のタイミングで情報の設定・更新がされるような場合は、タイミングなどに留意して設計する必要がある。

9 実装

TRANSACTION CONTEXTパターンにはいくつかのバリエーションがあり、検討すべき点がいくつかある。

  1. シングルスレッドのアプリケーション
    シングルスレッドのアプリケーションにおいては、Contextとして保持する情報はシステム全体で一意であり、スレッドIDなどをキーとしてトランザクション毎に保持する必要はない。
    そのような場合に、各アプリケーション毎に暗黙的に共有させたい情報がある場合は、ContextHolderオブジェクトを定義せず、ContextオブジェクトをSINGLETONとして用意すればよい。
  1. プロセス間通信
    プロセス間通信、あるいは別マシン間での通信の場合はContextを特定するためのキー情報をスレッドIDなどを使って簡単に取得することはできない。この場合は、明示的にキー情報をクライアントに指定させる方法の他、サーバー側でキー情報を自動生成し、Cookieなどを使って暗黙的に受け渡す方法などが考えられる。

リレーショナルデータベースのトランザクション制御をするために、このパターンを使った例を以下に示す。
(ConcreteDomainおよびConcretePersisterの役割については、永続化のためのデザインパターン PERSISTERを参照のこと。)

10 サンプルコード

省略

11 使用例

某社会計システム
某社在庫&販売管理システム

12 関連するパターン

13 参考文献

[1] Gamma, E. et al. Design Patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley, 1995