JDBC的连接池选项:DBCP vs C3P0

Java/JDBC可用的最佳连接池库是什么?

我正在考虑两个主要的候选(免费/开源):

我在博客和其他论坛上读了很多关于他们的文章,但无法做出决定。

有什么相关的替代方案吗?

212363 次浏览

另一个替代方案Proxool在这篇文章中提到。

您可能会发现为什么Hibernate在其默认连接池实现中捆绑c3p0 ?

DBCP已经过时,不能生产。前段时间,我们对这两者进行了内部分析,创建了一个测试fixture,针对这两者生成负载和并发性,以评估它们在现实生活条件下的适用性。

DBCP始终在我们的测试应用程序中生成异常,并且难以达到C3P0在没有任何异常的情况下处理的性能水平。

C3P0还健壮地处理了DB断开和恢复上的透明重新连接,而DBCP永远不会恢复连接,如果链接从下面被取出。更糟糕的是,DBCP将Connection对象返回给底层传输中断的应用程序。

从那时起,我们已经在4个主要的重载消费者web应用程序中使用了C3P0,并且从未回头。

更新:事实证明,经过多年的搁置,Apache Commons的人已经采取了DBCP脱离休眠状态,现在,再一次,一个积极开发的项目。因此,我原来的帖子可能已经过时了。

也就是说,我还没有体验过这个新升级的库的性能,也没有听说过它在任何最新的应用程序框架中。

对于与DBCP的自动重新连接问题,是否尝试使用以下2个配置参数?

validationQuery="Some Query"


testOnBorrow=true

不幸的是,它们都过时了。DBCP最近更新了一些,另外两个已经有2-3年的历史了,有很多突出的bug。

我邀请你尝试BoneCP——它是免费的,开源的,并且比可用的替代方案更快(参见基准测试部分)。

免责声明:我是作者,所以你可以说我有偏见:-)

更新:截至2010年3月,仍然比新重写的Apache DBCP(“tomcat jdbc”)池快35%左右。参见基准测试部分的动态基准测试链接。

更新#2:(12月13日)在顶部4年后,现在有一个更快的竞争对手:https://github.com/brettwooldridge/HikariCP

更新#3:(9月14日)此时请考虑BoneCP为弃用,建议切换到< >强HikariCP < / >强

更新#4:(2015年4月)—我不再拥有域名jolbox.com

以下是一些文章,它们表明DBCP的性能明显高于C3P0或Proxool。另外,根据我自己的经验,c3p0确实有一些不错的特性,比如预处理语句池,并且比DBCP更可配置,但是DBCP在我使用过的任何环境中都要快得多。

dbcp和c3p0的差异?绝对没有!(酒井的一个开发者博客) 罢工http://blogs.nyu.edu/blogs/nrm216/sakaidelic/2007/12/difference_between_dbcp_and_c3.html < / >

请在博客文章的评论中查看对JavaTech文章“连接池决战”的点赞。

我刚在DBCP上浪费了一天半时间。尽管我使用的是最新的DBCP版本,但我遇到了与j pimmel完全相同的问题。我完全不推荐DBCP,特别是它在DB消失时将连接从池中抛出,当DB返回时无法重新连接,并且无法动态地将连接对象添加回池中(它永远挂在JDBCconnect I/O套接字读取后)。

我现在切换到C3P0。我在以前的项目中使用过它,它的工作和表现就像一个魅力。

一个很容易使用的替代方法是DBPool

“一个基于java的数据库连接池实用程序,支持基于时间的过期、语句缓存、连接验证以及使用池管理器轻松配置。”

http://www.snaq.net/java/DBPool/

当连接超时时,我遇到了DBCP问题,所以我尝试了c3p0。我本打算将其发布到生产环境中,但随后开始了性能测试。我发现c3p0表现很糟糕。我根本无法将其配置得很好。我发现它比DBCP慢两倍。

然后我尝试了Tomcat连接池

这是c3p0的两倍快,并修复了我在DBCP中遇到的其他问题。我花了很多时间调查和测试这3个池子。如果要部署到Tomcat,我的建议是使用新的Tomcat JDBC池。

如果配置正确,Dbcp可以用于生产。

例如,它用于一个每天有350000访问者和200个连接池的商业网站。

只要配置正确,它就能很好地处理超时。

版本2正在进行中,它有一个背景,这使得它可靠,因为许多 生产问题已经解决。

我们使用它作为我们的批处理服务器解决方案,它已经运行了数百个批次,在数据库中工作数百万行。

由tomcat jdbc池运行的性能测试表明,它的性能优于cp30。

当我们使用多线程项目时,C3p0很好。在我们的项目中,我们使用DBCP同时执行多个线程,然后如果我们使用更多的线程执行,我们就会得到连接超时。所以我们用了c3p0位型。

已经在生产中使用DBCP好几年了。它是稳定的,生存DB服务器重启。只要正确配置即可。它只需要指定几个参数,所以不要偷懒。下面是我们系统生产代码中的一个片段,其中列出了我们显式设置的参数,以使其工作:

DriverAdapterCPDS driverAdapterCPDS = new DriverAdapterCPDS();
driverAdapterCPDS.setUrl(dataSourceProperties.getProperty("url"));
driverAdapterCPDS.setUser(dataSourceProperties.getProperty("username"));
driverAdapterCPDS.setPassword(dataSourceProperties.getProperty("password"));
driverAdapterCPDS.setDriver(dataSourceProperties.getProperty("driverClass"));


driverAdapterCPDS.setMaxActive(Integer.valueOf(dataSourceProperties.getProperty("maxActive")));
driverAdapterCPDS.setMaxIdle(Integer.valueOf(dataSourceProperties.getProperty("maxIdle")));
driverAdapterCPDS.setPoolPreparedStatements(Boolean.valueOf(dataSourceProperties.getProperty("poolPreparedStatements")));


SharedPoolDataSource poolDataSource = new SharedPoolDataSource();
poolDataSource.setConnectionPoolDataSource(driverAdapterCPDS);
poolDataSource.setMaxWait(Integer.valueOf(dataSourceProperties.getProperty("maxWait")));
poolDataSource.setDefaultTransactionIsolation(Integer.valueOf(dataSourceProperties.getProperty("defaultTransactionIsolation")));
poolDataSource.setDefaultReadOnly(Boolean.valueOf(dataSourceProperties.getProperty("defaultReadOnly")));
poolDataSource.setTestOnBorrow(Boolean.valueOf(dataSourceProperties.getProperty("testOnBorrow")));
poolDataSource.setValidationQuery("SELECT 0");

另一个替代方法是HikariCP

下面是比较基准

我们遇到了需要引入连接池的情况,我们面前有4个选项。

  • DBCP2
  • C3P0
  • Tomcat JDBC
  • HikariCP
我们根据自己的标准做了一些测试和比较,决定去HikariCP。 读取这篇文章来解释为什么我们选择HikariCP.

以最好的方式实现C3P0,然后检查这个答案

C3P0:

对于企业应用,C3P0是最好的方法。 C3P0是一个易于使用的库,用于用jndi绑定的数据源来增强传统的(基于drivermanager的)JDBC驱动程序,包括实现连接和语句池的数据源,如jdbc3规范和jdbc2 std扩展所描述的那样。 C3P0还健壮地处理了DB断开和恢复上的透明重新连接,而DBCP永远不会恢复连接,如果链接从下面被取出。< / p >

这就是为什么c3p0和其他连接池也有准备好的语句缓存——它允许应用程序代码避免处理所有这些。这些语句通常保存在一些有限的LRU池中,因此常见语句重用PreparedStatement实例。

更糟糕的是,DBCP将Connection对象返回给底层传输中断的应用程序。 c3p0的一个常见用例是替换Apache Tomcat中包含的标准DBCP连接池。通常情况下,程序员会遇到DBCP连接池中没有正确回收连接的情况,在这种情况下,c3p0是一个有价值的替换

在当前的更新中,C3P0有一些出色的功能。这些因素如下:

ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setMinPoolSize();
dataSource.setMaxPoolSize();
dataSource.setMaxIdleTime();
dataSource.setMaxStatements();
dataSource.setMaxStatementsPerConnection();
dataSource.setMaxIdleTimeExcessConnections();

这里,max和min poolsize定义了连接的边界,这意味着这个应用程序将接受的最小和最大连接。MaxIdleTime()定义何时释放空闲连接。

DBCP:

这种方法也很好,但有一些缺点,如连接超时和连接释放。 当我们使用多线程项目时,C3P0是很好的。在我们的项目中,我们使用DBCP同时执行多个线程,然后如果我们使用更多的线程执行,我们就会得到连接超时。所以我们用了c3p0位型。 我完全不推荐DBCP,特别是它在DB消失时将连接抛出池,当DB返回时无法重新连接,并且无法动态地将连接对象添加回池(它永远挂在JDBCconnect I/O套接字读取后)

谢谢:)

我的建议是

hikari >德鲁伊> UCP > c3p0 > DBCP

它是基于我所测试的- 20190202,在我的本地测试环境中(4GB mac/mysql in docker/pool minSize=1, maxSize=8), hikari可以服务1024个线程x 1024次来获得连接,每个线程完成的平均时间是1或2百万秒,而c3p0只能服务256个线程x 1024次,每个线程的平均时间已经是2100万秒。(512个线程失败)。