我想将同一个实体持久化到MySQL数据库和Postgres数据库(实际上一个是另一个的实时克隆)。从概念上讲,我想用一种方法做到这一点:
EntityManager mysql = ...;
EntityManager postgres = ...;
MyEntity e = new MyEntity();
e.setStuff();
mysql.persist(e);
postgres.persist(e);
MyEntity
类为其@GeneratedValue
字段指定IDENTITY
@Id
策略,两个数据源为非XA数据源。
JPA / JTA似乎想在分布式事务中执行此操作,我认为这是由于如何为容器管理的事务确定事务边界,并且因为数据源是非XA而出现错误。我可以将数据源定义为XA源,因此上述工作作为分布式事务,但是对于迫切需要,这实际上是不必要的。我真的不在乎这两个持续存在于同一个事务中 - 事实上,如果一个失败而另一个失败,那也没关系(至少目前为止)。
有没有办法将同一个对象持久化到具有非XA数据源的多个数据库,仍然使用容器管理的事务?相关的,如果我想在一个方法中对多个对象和多个数据源进行一系列持久化,是否有办法使用非XA数据源?我正在使用带有GlassFish 4.0的EclipseLink。
答案 0 :(得分:0)
嗯,没有发现如何使用容器管理的事务来完成它,而是使用bean管理的事务来完成它。注入一个UserTransaction资源,并将每个持久化包装在开始/提交对之间:
@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管理的事务,即使这不是生产用途而且不是特别优雅,如果这有一些根本性的错误,我会感谢有人指出正确的方法。