Javaでトランザクションのような機能を実現したい。データベースを更新する操作、キューに挿入する操作、別のデータ構造を更新する操作などのような ` n ' 操作を実行したいのですが、これらの操作はすべて 1 つのトランザクションとして動作する必要があります。操作は正常に実行される必要があります。そうでない場合、1 つが失敗すると、すべてが失敗するはずです。強引なアプローチの 1 つは、try-catch ブロックを記述し、catch ブロック内のすべての操作を元に戻すことです。この種の問題を解決するための指針はありますか? これを達成するためのパターンやライブラリはありますか?
5 に答える
いいえ、JTA が必要です。
強引な方法は、JDBC を使用してコミットとロールバックを自分で管理することです。
最も簡単な方法は、Spring または EJB3.1 と宣言型トランザクションを使用することです。
あなたが探しているパターンはCommandだと思います。
取引行動
元に戻すと同様に、データベース エンジンまたはソフトウェア インストーラーは、実行された、または実行される操作のリストを保持する場合があります。それらの 1 つが失敗した場合、他のすべてを元に戻すか破棄することができます (通常、ロールバックと呼ばれます)。たとえば、相互に参照する 2 つのデータベース テーブルを更新する必要があり、2 回目の更新が失敗した場合、トランザクションをロールバックして、最初のテーブルに無効な参照が含まれないようにすることができます。
これは、コマンド デザイン パターンと複合デザイン パターンを組み合わせて行いました。Transaction クラスは抽象的で、begin() および rollback() メソッドが含まれています。CompositeTransaction は Transaction から派生し、Transaction オブジェクトのリストを格納します。アトミック トランザクションとして処理する必要がある操作のグループごとに、CompositeTransaction のサブクラスを作成し、これに Transaction クラスを追加します。ここで CompositeTransaction を参照してください。
http://hillside.net/plop/plop99/proceedings/grand/plop_99_transaction_patterns.pdf
訪問者パターンはうまく機能します。また、適切なタイミングでコミットを発行する必要があります。一連の挿入/更新が完了するまで待ってからコミットを発行すると、説明した動作が自動的に行われるはずです。
暗黙のコミットなしでいくつかのステートメントを発行できるようにするために、SQLステートメントクラスの少しのリファクタリングが必要なようです。
これは、これをどのように達成できるかについての単なる論理です。
必要に応じて、トランザクションごとにメソッドを記述します。おそらく、それはすべてのリソースを持っているでしょう。jdbc トランザクションと同様に、要件として接続オブジェクトとクエリがあり、ファイル操作がある場合はファイル パスなどがあります。
したがって、5 つのトランザクションの場合、5 つの異なる方法があります。単一の方法でも実現できますが、これは単純にするためです。
例えば
method1(...) throws Exception {
...
// if any exception occurs then control will be passed to caller of this
// method
throw new Exception("1"); // write method number
}
次に、メソッドを次のように記述します (以下は単なるテンプレートです)。
public long/void transaction(...) throws Exception
{
try {
this.method1(...);
this.method2(...);
this.method3(...);
} catch (Exception e) {
// get that number in a exception message
// and try to undo all operations numbers less than above number.
// e.g. if that transaction method is any database transaction then
// try to rollback it.
// if it is creation of any file say log file then delete it
// now further logic depends on what the transaction was and how to
// undo it...
}
}
ありがとう。