2

我想将相同的实体持久保存到 MySQL 数据库和 Postgres 数据库(本质上是另一个的实时克隆)。从概念上讲,我想用一种方法来做到这一点:

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

该类为其字段MyEntity指定了一个@GeneratedValue策略,两个数据源都是非XA数据源。IDENTITY@Id

JPA/JTA 似乎想在分布式事务中执行此操作,我认为这是由于如何为容器管理的事务确定事务边界,并且由于数据源是非 XA 而出现错误。我可以将数据源定义为 XA 源,因此上述内容可用作分布式事务,但对于即时需要,这确实是不必要的。我真的不在乎这两个持久化是在同一个事务中——事实上,如果一个失败而另一个成功,那也很好(至少现在是这样)。

有没有办法将同一个对象持久化到具有非 XA 数据源的多个数据库中,并且仍然使用容器管理的事务?相关,如果我想在一个方法中对多个对象和多个数据源进行一系列持久化,有没有办法用非 XA 数据源做到这一点?我将 EclipseLink 与 GlassFish 4.0 一起使用。

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 回答