2

同じエンティティを MySQL データベースと Postgres データベースに保持したいと考えています (基本的に、一方は他方のリアルタイム クローンです)。概念的には、これを単一のメソッドで実行したいと考えています。

EntityManager mysql = ...;
EntityManager postgres = ...;
MyEntity e = new MyEntity();
e.setStuff();
mysql.persist(e);
postgres.persist(e);

MyEntityクラスはそのフィールドの@GeneratedValue戦略を指定し、2 つのデータ ソースは非 XA データ ソースです。IDENTITY@Id

JPA/JTA は、分散トランザクションでこれを行いたいようです。これは、コンテナー管理トランザクションのトランザクション境界がどのように決定されるかが原因であると考えられます。データ ソースが非 XA であるため、エラーが発生します。データ ソースを XA ソースとして定義できるので、上記は分散トランザクションとして機能しますが、差し迫った必要がある場合、それは本当に不要です。2 つの永続化が同じトランザクション内にあることはあまり気にしません。実際、一方が失敗し、もう一方が成功したとしても (少なくとも今のところは) 問題ありません。

XA 以外のデータ ソースを持つ複数のデータベースに同じオブジェクトを保持し、コンテナ管理のトランザクションを引き続き使用する方法はありますか? 関連して、1 つのメソッドで複数のオブジェクトと複数のデータ ソースを使用して一連の永続化を実行したい場合、非 XA データ ソースでそれを行う方法はありますか? GlassFish 4.0 で EclipseLink を使用しています。

4

1 に答える 1

0

コンテナ管理のトランザクションでそれを行う方法はわかりませんでしたが、Bean 管理のトランザクションでそれを行いました。UserTransaction リソースを注入し、各永続化を begin/commit ペアでラップしました。

@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class MyClass 
{
  @Resource private UserTransaction utx;

  public void doStuff() 
  {
    EntityManager mysql = ...;
    EntityManager postgres = ...;
    MyEntity e = new MyEntity();
    e.setStuff();
    try {
      utx.begin();
      mysql.persist(e);
      utx.commit();
      utx.begin();
      postgres.persist(e);
      utx.end();
    } catch (...) {
    ...
    }
  }
}

これまでに Bean 管理のトランザクションを使用したことはありません。これは本番用ではなく、特にエレガントでもありませんが、これに根本的な問題がある場合は、誰かが適切な方法を指摘していただければ幸いです。

于 2013-10-06T02:29:03.600 に答える