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

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

Apache DBCP - http://commons.apache.org/dbcp/ C3P0 - http://sourceforge.net/projects/c3p0

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

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


本文中还提到了另一种替代方案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:(2013年12月)在登顶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永远不会恢复连接,如果链接从下面被取出。

这就是为什么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();

在这里,最大池大小和最小池大小定义了连接的边界,即此应用程序将采用的最小连接和最大连接。MaxIdleTime()定义何时释放空闲连接。

DBCP:

This approach is also good but have some drawbacks like connection timeout and connection realeasing. C3P0 is good when we are using mutithreading projects. In our projects we used simultaneously multiple thread executions by using DBCP, then we got connection timeout if we used more thread executions. So we went with c3p0 configuration. I would not recommend DBCP at all, especially it's knack of throwing connections out of the pool when the DB goes away, its inability to reconnect when the DB comes back and its inability to dynamically add connection objects back into the pool (it hangs forever on a post JDBCconnect I/O socket read)

谢谢:)

我的建议是

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个线程失败)。