使用 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 数据库连接池)是不是仍然相关?