在javase数据库应用程序中,我处理了许多短期对象(比如账单等会计凭证)。
处理每个对象包括打开与数据库的连接并查找某些数据。并非所有对象都在同一个数据库中查找,但我根据某个对象属性选择了一个特定的数据库,因此我最终会打开几个连接。
我真正需要的是每个数据库只有一个连接
所以我做了类似的事情:
public MyPool {
Map<String, Connection> activeConnections = new TreeMap<String, Connection>();
public Connection getConnection(String database_name) throws SQLException {
if (activeConnections.containsKey(database_name)) {
return activeConnections.get(database_name);
}
//Retrive the configuration data from a configuration object
ConnectionConfig c = Configuration.getConnectionConfig(database_name);
Connection connection = DriverManager.getConnection(c.url, c.user, c.password);
return connection;
}
问题是:
1)因为我看到很多池库,DBCP,c3p0和其他库:所有这些库的重点是什么,它们为这样的“基本”方法添加了什么?
像this这样的教程对回答这个问题没什么帮助,因为这里公开的基本解决方案完全符合他们对连接池的定义。
2)这是一段代码,将“暴露”给其他开发人员,反过来可能会开发从具有不同结构的数据库中检索数据的过程,可能从这个“池对象”获得连接。 它是正确的,在文档和代码中,将它称为“池”,还是它是不同的东西,所以调用“池”会产生误导?
答案 0 :(得分:2)
由于每个数据源只有一个物理连接,因此在该术语的通俗使用中,您的代码不是连接池实现。对象池(在这种情况下,对象是连接)背后的概念是某些对象需要开销来配置。对于连接池,如您所知,必须先打开数据库连接,然后才能与数据库通信。
这里的区别在于,对于并发环境(例如您提到的流行连接池实现),您的代码不是线程安全的。在高并发环境(如Web)中运行的应用程序不应该承担在每个请求上建立连接的开销。相反,维护一个打开的连接池,当请求完成连接后,它将返回到池中以供后续使用请求。
这是必需的,因为连接是有状态的。您不能让多个请求同时共享同一个连接,并保证任何合理的事务语义。
答案 1 :(得分:1)
使用BoneCP并像这样包装连接池: 不要尝试创建自己的连接池,这就是BoneCP或任何其他非常好且经过良好测试的池的用途。
object ConnectionPool {
Class.forName("[ENTER DRIVER]")
private val connstring = [ENTER YOUR STRING]
private var cp : BoneCP = _
createConnectionPool() //upon init create the cp
/**
* Create a new connection pool
*/
def createConnectionPool() = {
if(cp == null) {
try {
val config = new BoneCPConfig()
config.setJdbcUrl(connstring)
config.setMaxConnectionsPerPartition(3)
config.setMinConnectionsPerPartition(1)
config.setPartitionCount(1)
cp = new BoneCP(config)
}
catch {
case e: SQLException => e.printStackTrace()
}
}
}
def getConnection () = { cp.getConnection }