35

ユーティリティのようなアプリケーションを隅に置き、2 つの異なるデータベースを定期的に更新しています。

これは、Spring Application Context で構築された小さなスタンドアロン アプリです。コンテキストには 2 つの Hibernate セッション ファクトリが構成されており、Spring で構成された Commons DBCP データ ソースを使用しています。

現在、トランザクション管理はありませんが、いくつか追加したいと思います。一方のデータベースの更新は、他方のデータベースの更新が成功するかどうかにかかっています。

アプリは Java EE コンテナー内に存在しません。シェル スクリプトから呼び出される静的ランチャー クラスによってブートストラップされます。ランチャ クラスはアプリケーション コンテキストをインスタンス化し、その Bean の 1 つでメソッドを呼び出します。

データベースの更新にトランザクション性を持たせる「最良の」方法は何ですか?

「最高」の定義はお任せしますが、「設定が簡単」「設定が簡単」「安価」「パッケージ化や再配布が容易」といった機能があればいいと思います。当然FOSSがいいでしょう。

4

5 に答える 5

41

トランザクションを複数のデータベースに分散するための最良の方法は、次のとおりです。

XAを指摘する人もいますが、XA(または2フェーズコミット)は嘘(またはマーケター)です。

想像してみてください。最初のフェーズでXAマネージャーに最終コミットを送信できることを通知した後、データベースの1つへのネットワーク接続が失敗します。それで?タイムアウト?これにより、他のデータベースが破損したままになります。ロールバック?2つの問題:コミットをロールバックできないことと、2番目のデータベースに何が起こったかをどのように知ることができますか?データのコミットに成功した後、ネットワーク接続が失敗し、「成功」メッセージのみが失われた可能性がありますか?

最善の方法は、データを1か所にコピーすることです。コピーを中止していつでも続行できるスキームを使用します(たとえば、既に持っているデータを無視するか、IDで選択を注文し、コピーのレコード> MAX(ID)のみを要求します)。これをトランザクションで保護します。ソースからデータを読み取るだけなので、これは問題ではありません。したがって、何らかの理由でトランザクションが失敗した場合は、ソースデータベースを無視できます。したがって、これは単純な古い単一ソーストランザクションです。

データをコピーしたら、ローカルで処理します。

于 2009-05-20T11:38:48.053 に答える
8

コンテキストでトランザクション マネージャーをセットアップします。Spring のドキュメントには例があり、非常に簡単です。次に、トランザクションを実行する場合:

try { 
    TransactionTemplate tt = new TransactionTemplate(txManager);

    tt.execute(new TransactionCallbackWithoutResult(){
    protected void doInTransactionWithoutResult(
            TransactionStatus status) {
        updateDb1();
        updateDb2();
    }
} catch (TransactionException ex) {
    // handle 
}

より多くの例と情報については、おそらくこれを見てください: Spring を使用した XA トランザクション

于 2008-09-24T17:20:28.883 に答える
5

「2 つの異なるデータベース」とは、異なるデータベース サーバーのことですか、それとも同じ DB サーバー内の 2 つの異なるスキーマのことですか?

前者の場合、完全なトランザクション性が必要な場合は、完全な 2 フェーズ コミットを提供する XA トランザクション API が必要です。しかし、さらに重要なことは、異なるデータベース システム間のトランザクションの伝播を管理するトランザクション コーディネーター/モニターも必要であることです。これは JavaEE 仕様の一部であり、かなり希少な部分です。TX コーディネーター自体は複雑なソフトウェアです。アプリケーション ソフトウェアは (必要に応じて Spring 経由で) コーディネーターと対話します。

ただし、同じ DB サーバー内の 2 つのデータベースを意味するだけであれば、通常の JDBC トランザクションは問題なく動作するはずです。単一のトランザクション内で両方のデータベースに対して操作を実行するだけです。

于 2008-09-28T12:11:20.050 に答える
3

分散 db トランザクションをサポートするSpring ChainedTransactionManager - http://docs.spring.io/spring-data/commons/docs/1.6.2.RELEASE/api/org/springframework/data/transaction/ChainedTransactionManager.htmlを試すことができます。これは、XA のより良い代替手段になる可能性があります

于 2014-06-12T00:08:28.850 に答える
3

この場合、トランザクション モニター (XA プロトコルをサポートするサーバー) が必要であり、データベースが XA もサポートしていることを確認してください。ほとんどの (すべて?) J2EE サーバーにはトランザクション モニターが組み込まれています。コードが J2EE サーバー以外で実行されている場合は、Atomicos、Bitronix などのスタンドアロンの代替手段が多数あります。

于 2008-12-28T17:15:07.247 に答える