如何在没有分布式事务的情况下使用JPA将同一对象持久化到两个不同的数据库? [英] How to use JPA to persist same object to two different db's without distributed transaction?

查看:23
本文介绍了如何在没有分布式事务的情况下使用JPA将同一对象持久化到两个不同的数据库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望将相同的实体持久化到MySQL数据库和Postgres数据库(本质上一个是另一个的实时克隆)。从概念上讲,我希望在单个方法中完成此操作:

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

MyEntity类为其@Id字段指定@GeneratedValue策略,两个数据源为非XA数据源。

JPA/JTA似乎希望在分布式事务中做到这一点,我认为这是由于容器管理的事务的事务边界是如何确定的,我得到了一个错误,因为数据源是非XA的。我可以将数据源定义为XA源,这样上面的内容就像分布式事务一样工作,但对于当前的需要来说,这真的没有必要。我真的不关心这两个持久化是不是在同一个事务中--事实上,如果一个失败而另一个成功,那也没问题(至少现在是这样)。

有没有办法将同一对象持久化到具有非XA数据源的多个数据库中,同时仍然使用容器管理的事务?如果我想在一个方法中对多个对象和多个数据源执行一系列持久化操作,有没有办法对非XA数据源执行此操作?我正在GlassFish 4.0上使用NikpseLink。

推荐答案

嗯,我没有发现如何使用容器管理的事务来做到这一点,但却发现了如何使用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管理的事务,尽管这不是用于生产用途,也不是特别优雅,但如果这从根本上有什么问题,我将非常感激有人指出正确的方法。

这篇关于如何在没有分布式事务的情况下使用JPA将同一对象持久化到两个不同的数据库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆