【问题标题】:Managing Multiple Database Connections管理多个数据库连接
【发布时间】:2014-11-13 12:07:39
【问题描述】:

我已经为这个问题苦苦挣扎了好几天,

这是场景: 我有几个数据库,每个客户都有一个,所有这些数据库都具有相同的 结构(相同的表和列),所以我的应用程序需要在运行时决定它需要连接哪个。我正在使用 JPA2、EclipseLink 和 EJB3。

我的第一次尝试是实现一个自定义 EntityManager,其中包含所有逻辑以在正确的数据库上执行操作,然后我将此 EntityManager 配置为无状态 EBJ,以便可以使用 @EBJ 注释注入它(如在此链接中描述:http://www.hostettler.net/blog/2012/11/20/multi-tenancy/)。我无法让它工作,因为它在尝试注入 EntityManager 时抛出异常。

所以我决定尝试其他方法,我创建了 EntityManagerFactory 并通过了 JTA_DATASOURCE 到它(在运行时决定使用哪一个之后),所以它可以连接到 正确的数据库。

代码如下:

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class TestEntDAO {

    private EntityManager em;
    private EntityManagerFactory emf;

    @PostConstruct
    public void init() {
        em = getEntityManager();
    }

    public EntityManager getEntityManager() {
        Map props = new HashMap();
        props.put(PersistenceUnitProperties.TRANSACTION_TYPE, "JTA");
        props.put(PersistenceUnitProperties.JTA_DATASOURCE, dataSourceName());
        emf = Persistence.createEntityManagerFactory("testePU", props);
        em = emf.createEntityManager();
        return em;
    }

    public String dataSourceName(){
        if(someCondition){
            return "db1";
        }else{
            return "db2";
        }
    }
}

这很完美,唯一的问题是事务不是由 容器,所以我必须明确标记事务的边界(调用 begin() 和 犯罪())。我可以使用 @PersistenceContext 注释使其工作,但后来我 不会有 EntityManagerFactory 来传递数据源。

有谁知道使用容器管理事务 (CMT) 并且仍然能够使用的方法 传递数据源?

【问题讨论】:

  • 为什么不能注入数据源名称?还是从属性文件中读取?
  • 我只是找不到一种方法来同时使用@PersistenceContext

标签: java database ejb eclipselink entitymanager


【解决方案1】:

也许尝试定义 3 个数据源和 3 个持久性单元。

<persistence-unit name="PU1">
  <jta-data-source>jdbc/DS1</jta-data-source>
  ...
</persistence-unit>
<persistence-unit name="PU2">
  <jta-data-source>jdbc/DS2</jta-data-source>
  ...
</persistence-unit>
<persistence-unit name="PU3">
  <jta-data-source>jdbc/DS3</jta-data-source>
  ...
</persistence-unit>

并从您想要的任何持久性单元中注入实体管理器。

@PersistenceContext(unitName = "PU2")
EntityManager em;

这应该可以,虽然我没有测试过。

【讨论】:

  • 我已经尝试过了,它成功了,但如果其中一个连接失败,应用程序将无法部署。
  • 也许可以克服。你遇到了什么错误?
  • 类似这样的东西 --> 内部异常:java.sql.SQLException:分配连接时出错。原因:无法分配连接,因为:连接尝试失败。
  • 考虑用完整的堆栈跟踪以及关于应用服务器和数据库的信息以及数据源配置提出一个新问题。
猜你喜欢
  • 1970-01-01
  • 2021-02-18
  • 2017-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
相关资源
最近更新 更多