【问题标题】:Get a DataSource/Connection from C3P0 connection pool从 C3P0 连接池获取数据源/连接
【发布时间】:2013-04-25 08:23:06
【问题描述】:

我正在使用一个库,我需要在其中获取数据源并将其输入其中。无论如何我可以从连接池中获得连接吗?我正在使用带有 C3p0 连接池的 Hibernate 4。

这是我的 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>

【问题讨论】:

    标签: java hibernate datasource connection-pooling c3p0


    【解决方案1】:

    如果您正在使用休眠并且想要访问它已经在使用的 c3p0 连接池,一种简单的方法是使用 C3P0Registry 类来查找数据源,请参阅herehere

    您可能会发现 getPooledDataSources() 返回一个包含单个元素的 Set,这就是 Hibernate 构建的 DataSource。如果需要,您还可以设置配置参数 c3p0.dataSourceName(hibernate 配置中的 hibernate.c3p0.dataSourceName),并使用 C3P0Registry.pooledDataSourcesByName(dataSourceName)。

    [如果您要设置自己的名称,则可能值得验证 hibernate 没有使用 dataSourceName 属性本身。我不认为它确实如此,但我没有检查过。最简单的检查方法是在 init 上查看池配置转储的日志,并确保其中有类似“dataSourceName -> z8kflt8uqkl8iymaxxkw|729f44”的内容。如果名称是带有管道的长随机字符串,则它是特定于实例的自动生成的身份令牌,您可以随意设置自己的名称。如果你看到一个更合理的名字,那么 hibernate 已经设置了这个属性并且可能期待你看到的名字,所以你应该查找那个名字。]

    请注意,如果您计划直接使用来自数据源的连接,请注意确保所有连接在 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 连接,community.jboss.org/wiki/HowToConfigureTheC3P0ConnectionPool 我在哪里可以设置 dataSourceName?还有你的 findUniqueDataSource 有什么用?为什么我可以直接使用 findDataSourceByName?
    • 我不肯定,但可能 appDataSource 将用于在那里设置 dataSourceName 参数。如果您没有设置 dataSourceName,您将使用 findUniqueDataSource,因为您无法预测自动生成的名称。
    • 感谢您提供信息,如果愿意/帮助/添加信息,我更新了我的问题以包括我的 hibernate.cfg.xml
    • 顺便说一句,我怎样才能关闭数据源或将数据源返回到池中?
    【解决方案2】:

    c3p0 为 Hibernate 提供连接池,因为 内置的 Hibernate 连接池绝不是用于生产用途的。它缺少在任何体面的连接池上发现的一些功能 - 根据Hibernate Community Documentation,关于使用 Hibernate 配置 c3p0,您可以参考 Hibernate 社区上的 thisMKYong 教程。

    【讨论】:

    • 我已经使用第一个链接配置了我的 C3P0 连接池,无论如何我可以从连接池中获取连接/数据源吗?因为我需要它并在我的代码中的某个地方传递它。
    猜你喜欢
    • 2013-08-20
    • 2011-05-28
    • 2012-01-15
    • 2016-09-16
    • 2016-07-08
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多