我正在运行一个使用Tomcat 8服务器中的Hibernate的应用程序。我想利用除Hibernate之外的其他连接池,因为它们很明显它不适合在生产环境中使用。
另外,他们提到:
要在应用程序服务器中使用,您几乎应该始终配置Hibernate以从JNDI中注册的应用程序服务器javax.sql.Datasource获取连接。
所以我觉得我需要做两件事:
javax.sql.Datasource
对象我一直在研究如何做出这些改变,我遇到了this所以问题。海报已经在使用C3PO,并询问如何通过JNDI Datasource
对象连接到他们的数据库。然而,他们遇到了问题,因为他们已经在使用C3PO,而他们正在遵循回答者使用JNDI数据源的步骤。海报在接受的答案的评论部分说了这个:
是的,我在那里使用c3p0和JNDI一直很傻。我删除了所有c3p0配置,现在工作正常。
Hibernate建议使用第三方连接池,即C3PO,并使用JNDI数据源来接收连接,但它似乎对该用户造成了问题;他们甚至谈到同时使用它们就好像这是一个明显的错误。
所以我不能同时使用它们,或者我应该像Hibernate推荐的那样使用它们吗?我所要做的就是将Hibernate的默认连接池替换为打算在生产环境中使用的池,并将Hibernate配置为从JNDI中注册的javax.sql.Datasource
对象获取连接,如他们所推荐的那样。 / p>
答案 0 :(得分:4)
我会尽力清理混乱。
我认为它从简单的DataSource接口开始:https://docs.oracle.com/javase/7/docs/api/javax/sql/DataSource.html
DataSource接口由驱动程序供应商实现。有 三种类型的实现:
- 基本实现 - 生成标准Connection对象
- 连接池实现 - 生成一个将自动参与连接池的Connection对象。这个 实现适用于中间层连接池管理器。
- 分布式事务实现 - 生成一个可用于分布式事务的Connection对象,几乎总是如此 参与连接池。这个实现适用于 中间层事务管理器,几乎总是有连接 合并经理。
醇>
Hibernate需要使用DataSource,并建议它使用连接池。
C3PO包装现有的DataSource并对其应用连接池,并创建一个类型为2的新DataSource.C3PO假定它获取的DataSource是类型1,但无法确定。
在其他应用程序服务器中,如果声明在JNDI中注册的数据源,它几乎总是使用容器中已有的连接池。对于Tomcat 8,它在内部使用C3PO。
因此,有两种方法可以在Hibernate中实现连接池:创建类型1数据源并将其嵌入到代码中的连接池中,或者在容器中声明数据源(带连接池),并将其从hibernate中注入JNDI。
如果您同时执行这两项操作,则应用程序中的C3PO会从JNDI获取数据源,而JNDI本身就是由tomcat管理的C3PO数据源。当应用程序尝试获取连接时,应用程序C3PO将调用容器C3PO,这将创建实际连接,但连接将在两个连接池中池化。当hibernate释放连接时,应用程序C3PO将保留它以供重用,但另一个连接池将继续等待连接被释放。
根据配置的不同,底层连接池可能会在超时后终止连接。
因此,将两个连接池相互配置是危险的,完全没必要。
回答赏金问题:在生产环境中,在生产容器中声明数据源,并通过JNDI将其连接到Hibernate,而不在Hibernate中配置任何其他连接池。
答案 1 :(得分:1)
在参考SO帖子中,海报从已经由Hibernate配置的C3PO开始。当海报移动到获得对已配置的 C3PO连接池的JNDI引用时,他/她认为Hibernate在启动期间正在处理配置。解决方案是将C3PO配置移动到容器(Tomcat)并从Hibernate设置中删除配置。
以下是应用程序启动的简要概述:
在Web应用程序部署阶段,读取Hibernate配置并发出JNDI资源请求。由于已经配置了C3PO,因此不会看到在Hibernate中完成的任何配置。