使用 Apache DBCP 进行连接池

Posted

技术标签:

【中文标题】使用 Apache DBCP 进行连接池【英文标题】:Connection Pooling with Apache DBCP 【发布时间】:2013-01-06 05:02:36 【问题描述】:

我想使用Apache Commons DBCP 在 Java 应用程序中启用连接池(这里没有容器提供的数据源)。在网络的许多站点中 - 包括 Apache site - 库的使用基于此 sn-p:

BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
ds.setUsername("scott");
ds.setPassword("tiger");
ds.setUrl(connectURI);  

然后你通过 getConnection() 方法获得你的数据库连接。但在其他网站上 - 和 Apache Site also- 数据源实例是通过以下方式创建的:

ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(connectURI,null);
PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory);
ObjectPool objectPool = new GenericObjectPool(poolableConnectionFactory);
PoolingDataSource dataSource = new PoolingDataSource(objectPool);

它们之间有什么区别?我正在使用带有BasicDataSource 的连接池,或者我需要一个PoolingDataSource 的实例来使用连接池? BasicDataSource 是线程安全的(我可以将其用作 Class 属性)还是需要同步其访问?

【问题讨论】:

【参考方案1】:

BasicDataSource 满足基本需求。 它在内部创建一个 PoolableDataSource 和一个 ObjectPool。

PoolableDataSource 使用提供的 ObjectPool 实现 DataSource 接口。 PoolingDataSource 负责连接,ObjectPool 负责持有和计数这个对象。

我会推荐使用 BasicDataSource。 只是,如果你真的需要一些特别的东西,那么你可以将 PoolingDatasource 与 ObjectPool 的另一个实现一起使用,但这将非常罕见和具体。

BasicDataSource 是线程安全的,但您应该注意使用适当的访问器,而不是直接访问受保护的字段以确保线程安全。

【讨论】:

“适当的访问者”是什么意思?同步块? BasicDataSource 是线程安全的,因为所有变量都是通过同步读取/写入的。所以,我认为你不需要使用同步块。如果您要扩展此类,则应注意使用适当的访问器,而不是直接访问受保护的字段以确保线程安全,但您不需要使用同步块。【参考方案2】:

这更像是对 ivi 上述答案的(大)支持评论,但由于需要添加快照,因此将其作为答案发布。

BasicDataSource 满足基本需求。它在内部创建一个 PoolableDataSource 和 ObjectPool。

我想查看 BasicDataSource 中的代码来证实该陈述(事实证明这是真的)。我希望以下快照对未来的读者有所帮助。


当第一次执行basicDatasource.getConnection() 时会发生以下情况。第一次围绕DataSource创建如下:


    这是原始连接工厂。

    这是在其余步骤中使用的通用对象池 ('connectionPool')。

    这结合了以上两个(connectionFactory +一个Object Pool)来创建一个PoolableConnectionFactory。 值得注意的是,在创建 PoolableConnectionFactory 期间,connectionPool 与 connectionFactory 链接如下:

    最后,从connectionPool创建一个PoolingDataSource

【讨论】:

以上是关于使用 Apache DBCP 进行连接池的主要内容,如果未能解决你的问题,请参考以下文章

连接池

DBCP(Apache Commons 数据库连接池)是不是仍然相关?

mysql连接超时后无法从apache DBCP连接池获取连接

数据库连接池DBCP的使用

DBCP数据库连接池的简单使用

DBCP数据库连接池的简单使用