web-dev-qa-db-ja.com

SpringとHibernateを使用して複数のデータベース間で分散トランザクションを実行するための「最良の」方法は何ですか

私は、隅にあり、2つの異なるデータベースを定期的に更新するアプリケーション(ユーティリティのようなもの)を持っています。

これは、Springアプリケーションコンテキストで構築された小さなスタンドアロンアプリです。コンテキストには2つのHibernateSession Factoryが構成されており、Springで構成されたCommonsDBCPデータソースを使用します。

現在、トランザクション管理はありませんが、追加したいと思います。一方のデータベースへの更新は、もう一方への更新の成功に依存します。

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

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

「最良」の定義はあなたにお任せしますが、「セットアップが簡単」、「構成が簡単」、「安価」、「パッケージ化と再配布が簡単」の機能である必要があると思います。当然FOSSがいいでしょう。

29
Vihung

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

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

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

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

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

30
Aaron Digulla

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

try { 
    TransactionTemplate tt = new TransactionTemplate(txManager);

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

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

6

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

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

ただし、同じDBサーバー内の2つのデータベースを意味する場合は、Vanilla JDBCトランザクションは問題なく機能し、1つのトランザクション内で両方のデータベースに対して操作を実行するだけです。

5
skaffman

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

3

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

3
maximdim