1

我正在使用 Hibernate 编写 Java SE(注意,不是Java EE)应用程序,并且我需要为每个执行线程提供到 Hibernate 的不同连接。这些连接必须汇集在一起​​,并且每个连接至少具有不同的身份验证,并且可能具有不同的 JDBC URL。连接将被重新使用(可以从池化需求中推断出来)。

我必须覆盖 Hibernate/C3P0/et al 的哪些部分?这可以通过这些工具来完成,还是我需要编写自己的池数据源?

4

2 回答 2

1

您在这里有两个问题:

  1. 连接不是线程安全的,因此每个线程必须有自己的连接。由于您使用的是 Hibernate,因此您的应用程序看到的实际上是从 SessionFactory 获得的 Session。要利用它,您调用 SessionFactory#getCurrentSession() 方法,并在 hibernate.cfg.xml 中配置当前会话上下文:
    <property name="current\_session\_context\_class">线程</property>
    如果您在 hibernate.cfg.xml 中正确配置了线程池(使用 c3po 或您喜欢的任何池机制),那么每个线程都会从该池中获得一个连接。
  2. 要维护应用程序可能需要使用的多个数据源,您需要为要访问的每个 JDBC url 配置单独的 SessionFactory。在您的应用程序中,您需要有一些使用 SessionFactory 进行选择的方法,您需要选择(例如“客户端 ID”),使用它您可以管理 Map 或某种此类数据结构中的每个 SessionFactory 实例(在 Java EE 应用程序,您将从 JNDI 获得参考)。

总结(和概括),基本上 SessionFactory 本质上是围绕数据源(和伴随的连接池)的巨大包装器。它是只读的(因此是线程安全的)、重量级和静态的,一次构建,并且知道它需要的关于给定 DataSource 的一切。

另一方面,会话本质上是围绕连接的轻量级包装器。它不是线程安全的,通常是短暂的,并且打算使用然后丢弃。

希望这可以帮助!

于 2009-04-24T01:13:39.667 回答
1

我认为最好的做法是SessionFactory为每个数据源创建一个,并可能使用池连接——这就是 eqbridges 在他的回答中所建议的。

现在,Hibernate 确实有一个ConnectionProvider钩子,所以我想您可以编写一个实现,将Connections 返回到不同的数据源,具体取决于当前的执行线程和一些附加参数。理论上,您可以拥有一个SessionFactory实例,该实例将使用与不同数据库的不同连接,由您的自定义ConnectionProvider实现提供。但是,一个人SessionFactory拥有相当多的数据,然后当为一个工作单元打开 a 时,这些数据会被 Hibernate 在内部使用Session。另外,还有一个与之相关的二级缓存。

不幸的是,Session任何人都在猜测,面对这样的供应商,工厂和您从中打开的工厂将如何表现。这对我来说就像是一种黑客行为,我怀疑它曾经被认为是一个可行的SessionFactory. 它可能会导致各种可能非常微妙的错误或数据损坏。

另一方面,一定要准确衡量创建多个的成本SessionFactories——它可能没有你想象的那么高。请务必将其与仅打开所需 JDBC 连接的成本进行比较。我不知道你可能会得到什么样的结果,但我认为你应该先确定性能,然后再求助于更骇人听闻的解决方案。

于 2009-04-24T19:35:13.420 回答