トランザクション処理は技術基盤が主に関わる低次元な役割です。
普通に書くと「アプリケーションサービス」に対してトランザクションを記述しなければならなくなるでしょう。
そうすると、特定の技術基盤に「アプリケーションサービス」が依存してしまうことになります。
ではどうするか?
そもそも、ビジネス上も整合性というのは非常に大きな概念であり高次元の概念ではあります。なので、詳細な処理は確かに低次元ですが、ビジネスロジックの整合性担保のために、トランザクションの開始と終了を主張することは悪いことではないのです。
各言語ごとに対策があります。
C#
トランザクションスコープを使う。
1 2 3 4 5 |
using(var transaction = new TransactionScope()) { // 登録処理1 // 登録処理2 transaction.Complete(); } |
Java
AOP(アスペクト指向プログラミング)を使う。要は「@Transaction」というアノテーションをメソッドの前に付加したりして明示できます。
1 2 3 4 5 |
@Transaction(isolation = Isolation.SERIALIZABLE) public void メソッド名() { // 登録処理1 // 登録処理2 } |
ユニットオブワークを利用する。
ユニットオブワーク
オブジェクトの変更を記録するオブジェクトです。オブジェクトの読み取り動作を行う際にインスタンスの状態を記録します。読み取られたオブジェクトの変更、削除はユニットオブワークに通知しない限りはデータストアに反映されないです。
1 2 3 4 5 |
class ユニットオブワーク { 登録メソッド(object value); 削除メソッド(object value); コミット(); } |
上記のようにユニットオブワークのメソッド内でトランザクションの制御などを委譲してそれをアプリケーションサービスから呼び出して使うようにします。
詳細な実装方法についてはC#のEntity Frameworkがユニットオブワークを実装した形になっているのでそちらを参考するようにすれば良いでしょう。
現実としてどれを使うか
基本的には宣言的に使えた方が良いのでC#であればトランザクションスコープを使った方が良いですし、JavaであればAOPで実装した方が良いでしょう。もし、AOPがない言語の場合はAOPに準ずるライブラリなどを使用するようにすると良いでしょう。
この記事へのコメントはありません。