从C3P0连接池获取数据源/连接
我正在使用一个库,我需要获取数据源并将其提供给它。无论如何,我可以从连接池中获得连接吗?我正在使用Hibernate 4和C3p0连接池。从C3P0连接池获取数据源/连接
,这里是我的hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/sampleDB</property>
<property name="connection.username">root</property>
<property name="connection.password">mypass</property>
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="c3p0.max_size">100</property>
<property name="c3p0.min_size">1</property>
<property name="c3p0.idle_test_period">30</property>
<!-- SQL dialect -->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!-- Shows Generated SQL Queries By Hibernate -->
<property name="show_sql">false</property>
<!-- Drop and re-create The Database Schema on Start up -->
<property name="hbm2ddl.auto">update</property>
<property name="cache.provider.class">org.hibernate.cache.NoCacheProvider</property>
</session-factory>
</hibernate-configuration>
如果您正在使用hibernate并希望访问它已在使用的c3p0连接池,则一种简单的方法是使用C3P0Registry类查找数据源,请参阅here和here。
您可能会发现getPooledDataSources()返回一个包含单个元素的Set,并且这将是Hibernate构造的DataSource。如果你愿意,你也可以设置配置参数c3p0.dataSourceName(在hibernate配置中的hibernate.c3p0.dataSourceName),并使用C3P0Registry.pooledDataSourcesByName(dataSourceName)。
[如果您要设置自己的名称,那么可能需要验证hibernate没有使用dataSourceName属性本身。我不认为它确实如此,但我没有检查。检查最简单的方法是查看日志中的init config pool dump,并确保其中包含“dataSourceName - > z8kflt8uqkl8iymaxxkw | 729f44”。如果这个名字是一个很长的random-ish字符串,并且有一个管道,那么它就是一个特定于实例的自动生成的身份标记,您应该随意设置自己的名字。如果你看到一个更明智的名字,那么hibernate已经设置了这个属性,并且可能期待你看到的名字,所以你应该查找这个名字。]
请注意,如果你打算直接使用来自DataSource的连接,注意确保所有连接在finally块中正确关闭()。如果你“泄漏”连接,即如果你检查出它们并且无法可靠地检查它们,你最终会耗尽池并冻结你的休眠应用程序。
祝你好运!
更新:例...
import java.util.Set;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.C3P0Registry;
// you probably want better Exception handling than this...
private DataSource findUniqueDataSource()
{
Set set = C3P0Registry.getPooledDataSources();
int sz = set.size();
if (sz == 1) // yay, just one DataSource
return (DataSource) set.iterator().next();
else
throw new RuntimeException("No unique c3p0 DataSource, found:" + sz);
}
// be sure you have configured a dataSourceName in your c3p0 or hibernate config
private DataSource findDataSourceByName(String dataSourceName)
{ return C3P0Registry.pooledDataSourceByName(dataSourceName); }
不,你不应该“泄漏”连接,并期望池后面进行清理。您可以忘记关闭语句和结果集,并且在关闭连接时池会关闭它们,但池不知道时可以安全地从连接失败的客户端抓取连接它。有些应用程序长时间保持连接打开状态(尽管如果您使用的是连接缓冲池,那么这是不好的做法)。
您可以强制 c3p0在一段时间后清理泄漏的连接,请参阅配置参数unreturnedConnectionTimeout。但这是一个棘手的策略;我建议如果您有泄漏,只能暂时与debugUnreturnedConnectionStackTraces一起使用,以了解您连接泄漏的位置,然后解决问题。
C3P0提供连接池对Hibernate,为内置的Hibernate连接池不用于产品使用。它缺少在任何体面的连接池上发现的几个功能 - 根据Hibernate Community Documentation,对于使用Hibernate配置c3p0,可以参考this或MKYong关于Hibernate Community的教程。
我已经使用第一个链接配置了我的C3P0连接池,无论如何,我可以从连接池中获得连接/数据源?因为我将需要它并将其传递到我的代码中的某处。 – user962206 2013-05-01 11:12:19
你能举例说明如何做到这一点吗?如果我“泄漏”连接,我认为它会自动关闭? – user962206 2013-05-01 11:16:06
查看上面的更新。 – 2013-05-01 11:55:59
谢谢,虽然我目前正在使用它来设置我的c3p0连接,https://community.jboss.org/wiki/HowToConfigureTheC3P0ConnectionPool在哪里可以设置dataSourceName?你的findUniqueDataSource有什么用处?为什么我可以直接使用findDataSourceByName? – user962206 2013-05-01 12:00:46