3

Java Transactions API (JTA) とその実装の 1 つである Bitronix の下にあるに頭を悩ませようとしています。しかし、ドキュメンテーションを深く掘り下げていくと、次の簡単な例を考えずにはいられません。

public interface Transactional {
    public void commit(Object);
    public void rollback();
}

public class TransactionalFileWriter extends FileWriter implements Transactional {
    @Override
    public void commit(Object obj) {
        String str = (String)obj;

        // Write the String to a file.
        write(str);
    }

    @Override
    public void rollback() {
        // Obtain a handler to the File we are writing to, and delete the file.
        // This returns the file system to the state it was in before we created a file and started writing to it.
        File f = getFile();

        // This is just pseudo-code for the sake of this example.
        File.delete(f);
    }
}

// Some method in a class somewhere...
public void doSomething(File someFile) {
    TransactionalFileWriter txFileWriter = getTxFW(someFile);
    try {
        txFileWriter.commit("Create the file and write this message to it.");
    } catch(Throwable t) {
        txFileWriter.rollback();
    }
}

上記の実際のコードにとらわれすぎないでください。アイデアは単純です。ファイルを作成して書き込むトランザクション ファイル ライターです。このrollback()メソッドはファイルを削除するため、ファイル システムはcommit(Object).

ここで何か不足していますか?JTA が提供するのはこれだけですか? それとも、上記の単純な例では表されていない、トランザクションに対する次元/側面のまったく異なるセットがありますか? 私は後者を推測していますが、JTA ドキュメントにはまだ具体的なものは何もありません。何かが足りない場合、それは何ですか?具体的な例を教えてもらえますか? トランザクション性が JDBC の巨大なコンポーネントであることは理解できますが、うまくいけば、データベース以外のもので動作する JTA の例を取得したいと考えています。

4

2 に答える 2

8

誰もが言及しているように、JTA の主な利点は単一のトランザクション ケースではなく、複数のトランザクションのオーケストレーションです。

あなたの「トランザクションファイル」は、適切なコンテキストで使用された場合の優れた概念的な例です。

不自然なユースケースを考えてみましょう。

関連付けられたメタデータを持つ画像をアップロードし、ファイルが到着したことをインフラストラクチャに警告したいとします。

この「単純な」タスクには、信頼性の問題がつきものです。

たとえば、次のワークフロー:

String pathName = saveUploadedFile(myFile);
saveMetaData(myFile.size(), myFile.type(), currentUser, pathName);
queueMessageToJMS(new FileArrivalEvent(user, pathName);

このコードには、ファイル システムと 2 つの異なるサーバー (DB と JMS) が含まれます。

saveUploadedFile が成功しても、saveMetaData が成功しない場合、ファイル システムに孤立したファイル、いわば「ファイル リーク」があります。saveMetaData が成功してもキューが成功しない場合、ファイルは保存されていますが、「誰もそれについて知りません」。トランザクションの成功は、3 つのコンポーネントすべてがタスクを正常に実行することにかかっています。

次に、JTA (実際のコードではありません) を投入します。

beginWork();
try {
    String pathName = saveUploadedFile(myFile);
    saveMetaData(myFile.size(), myFile.type(), currentUser, pathName);
    queueMessageToJMS(new FileArrivalEvent(user, pathName);
} catch(Exception e) {
    rollbackWork();
} finally {
    commitWork();
}

これで、「すべてが機能する」または「どれも機能しない」ようになります。

ほとんどのシステムにはトランザクション マネージャーがないため、通常、人々はこの種のことを安全に動作させるために、さまざまな手段を講じます。しかし、トランザクション マネージャー (つまり JTA) を使用すると、TM がすべての作業を管理してくれるので、コードをきれいに保つことができます。

業界を調査すると、トランザクション マネージャーはほとんど見つかりません。もともとは、「エンタープライズ」グレードのシステムで使用される独自のプログラムでした。TIBCO が有名で、IBM が 1 つ、Microsoft が 1 つです。昔はタキシードが流行った。

しかし、Java、JTA、およびユビキタスな Java EE (など) サーバーでは、「誰もが」トランザクション マネージャーを持っています。私たち Java の世界では、このオーケストレーションを「無料」で入手できます。そしてあると便利です。

Java EE により、トランザクション マネージャーがユビキタスになり、トランザクション処理がバックグラウンドで考慮されるようになりました。Java EE は、「commit() を再度記述する必要がない」ことを意味します。(明らかに、Spring も同様の機能を提供しています)。

ほとんどのシステムでは、必要ありません。そのため、ほとんどの人はそれについてあまり知らないか、単に見逃していません. ほとんどのシステムは、単一のデータベースにデータを入力するか、単に複数のシステムのオーケストレーションに関する問題を心配する必要がありません。プロセスは損失を伴う可能性があり、独自のクリーンアップメカニズムが組み込まれています。

でも、必要なときはとてもいいです。複数のシステムに同時にコミットすることで、多くの頭痛の種が解消されます。

于 2014-07-01T14:43:40.137 に答える
1

JTA の最大の特徴は、1 つのアプリケーションで複数のトランザクション ストアを構成し、これらの独立したストアにまたがるトランザクションを実行できることです。

たとえば、DB、分散トランザクション キー値ストア、単純な FileWriter を用意し、これらすべてに対して操作を実行し、すべてのストアのすべての変更を一度にコミットするトランザクションを作成できます。

infinispanを見てください。これはトランザクション データ グリッドであり、JTA を使用し、他の JTA トランザクション サービスと組み合わせて使用​​できます。

編集:

基本的に、JTA はX/Open XA標準に接続されており、Java コードで直接 X/Open XA リソースと対話する手段を提供します。データベース、分散データ グリッドなど、X/Open XA 準拠のリソースを保持する既存のデータ ストアを使用できます。または、 javax.transaction.xa.XAResourceを実装して独自のリソースを定義できます。次に、ユーザー トランザクションがこれらのリソースを使用すると、リソースがどこにあり、どのデータストアにあるかに関係なく、トランザクション マネージャーがすべてを調整します。

ビジネス全体は、独立したデータ ストアの同期を担当するトランザクション マネージャーによって管理されます。JTA にはトランザクション マネージャーが付属していません。JTA は単なる API です。必要に応じて ( javax.transaction.TransactionManager ) 独自のものを作成することもできますが、明らかにそれは難しい作業です。代わりに、トランザクション マネージャーを備えた、既に実装されている JTA サービス/ライブラリを使用することをお勧めします。たとえば、アプリケーションで infinispan を使用する場合、そのトランザクション マネージャーを使用して、トランザクションがさまざまなデータ ストアとやり取りできるようにすることができます。これを達成する方法については、JTA インターフェースの実装者からさらに情報を得ることが最善です。

かなり長いですが、完全な JTA API ドキュメントはこちらにあります。Java EE トランザクション マネージャーの使用方法と複数のデータ ストアの更新方法について説明しているチュートリアルもいくつかありますが、かなりわかりにくく、コード サンプルも提供されていません。

Infinispan のドキュメントとチュートリアルを確認できますが、Infinispan を他のデータストアと組み合わせた例は見当たりません。

編集2:

コメントからあなたの質問に答えるには: あなたの理解は多かれ少なかれ正しいですが、私はそれをさらに明確にしようとします.

アーキテクチャを説明し、質問に絵で答える方が簡単です。以下は JTA 仕様 1.1 からの抜粋です。

これは X/Open XA アーキテクチャです。

X/Open XA アーキテクチャ

各データ ストア (データベース、メッセージ キュー、SAP ERP システムなど) には、独自のリソース マネージャーがあります。リレーショナル データベースの場合、JDBC ドライバーは、Java でデータベースのリソース マネージャーを表すリソース アダプターです。各リソースは、XAResource インターフェースを介して使用できる必要があります (特定のデータストアの実装の詳細を知らなくても、Transaction Manager がリソースを管理できるようにするため)。

アプリケーションは、リソース アダプタによってリソース マネージャ (特定のリソースへのアクセスを取得するため) と、UserTransaction インターフェイスによってトランザクション マネージャ (トランザクションを開始/終了するため) の両方と通信します。各リソース マネージャーは最初に初期化する必要があり、グローバル トランザクション (つまり、複数のデータ ストアにまたがる) 用に構成する必要があります。

基本的に、はい、データストアはいくつかのリソースをグループ化する独立した論理ユニットです。また、ローカル トランザクション (特定のデータ ストアに限定) を実行できるインターフェイスも示します。このインターフェースはパフォーマンスが向上するか、JTA インターフェースでは使用できないデータストア固有の追加機能を公開する可能性があります。

これは JTA 環境のアーキテクチャです。

JTA アーキテクチャ

小さな半円は JTA インターフェイスを表します。あなたの場合、主に JTA UserTransaction インターフェースに興味があります。EJB (トランザクション Bean) を使用することもでき、アプリケーション サーバーがトランザクションを管理しますが、それは別の方法です。

トランザクション マネージャの観点からは、トランザクション サービスの実際の実装を公開する必要はありません。トランザクションの境界設定、リソースの登録、同期、および回復プロセスをトランザクション サービスのユーザーから実行できるように定義する必要があるのは、高レベルのインターフェイスだけです。

そのため、Transaction Manager は、JTS 実装などのトランザクションを管理するために使用される実際のメカニズムのみを表すインターフェイスとして理解できますが、それを全体として考えることもエラーではありません。

私の理解では、たとえばJBossアプリケーションサーバーを実行している場合、基盤となるトランザクションサービス実装を備えたトランザクションマネージャーがすでに装備されています。

于 2014-07-01T14:00:54.720 に答える