用 H2 数据库理解 JdbcConnectionPool
Posted
技术标签:
【中文标题】用 H2 数据库理解 JdbcConnectionPool【英文标题】:Understanding JdbcConnectionPool with H2 database 【发布时间】:2014-11-21 19:44:08 【问题描述】:我的主服务器机器上运行着一个 H2 服务器进程,允许 TCP 连接。
假设我要执行 100 个 SQL 查询:
SELECT * FROM TEST
而且,出于我自己的目的,我想对每个线程进行一次查询。让我们在线程之间共享一个且只有一个 Connection
对象:
Connection
对象。
创建 100 个线程。
在每个线程中,使用共享的Connection
对象调用SQL 查询。
上述方法可行,但会有点慢。当然,毕竟如果有人用Connection
,那其他人就得等了。
那么,让我们为每个线程创建一个Connection
:
Connection
对象并调用SQL 查询。
快得多。但我觉得 100 个连接有点浪费。也许 50 个连接就可以了。听说这种事情可以用JdbcConnectionPool
。
JdbcConnectionPool
。
创建 100 个线程。
在每个线程中,使用pool.getConnection()
,然后调用SQL查询。
嗯。它很慢。如果有的话,它和第一种方法一样慢。也许,出于好奇,我应该将最大连接数设置为100
...
...它仍然很慢。奇怪的。我的理解是,一个有 100 个连接的池相当于为我的 100 个线程中的每个线程建立一个连接。
可能是什么问题?这是最后一次测试的代码:
import java.sql.Connection;
import java.sql.ResultSet;
import org.h2.jdbcx.JdbcConnectionPool;
public class App
public static void main(String[] args) throws Exception
Class.forName("org.h2.Driver");
JdbcConnectionPool pool = JdbcConnectionPool.create("url", "user", "password");
pool.setMaxConnections(100);
for (int i = 0; i < 100; ++i)
Thread t = new Thread(new Client(i, pool));
t.start();
class Client implements Runnable
int id;
JdbcConnectionPool pool;
public Client(int id, JdbcConnectionPool pool)
this.id = id;
this.pool = pool;
public void run()
try
Connection conn = pool.getConnection();
ResultSet set = conn.createStatement().executeQuery("SELECT * FROM TEST");
if (set.next())
System.out.println("Finished " + id);
set.close();
conn.close();
catch (Exception e)
我正在使用H2 1.4.182
。
【问题讨论】:
最后你变成用什么连接池了,可以看看例子吗? @user2602807 我相信当时的这个项目是一样的 -JdbcConnectionPool
。答案是正确的:由于初始化,它很慢,但之后它就像预期的那样快。所以基本上我在问题中发布的示例很好 - 它只需要预热。
【参考方案1】:
JdbcConnectionPool#getConnection()的源码:
public Connection getConnection() throws SQLException
long max = System.currentTimeMillis() + timeout * 1000;
do
synchronized (this)
if (activeConnections < maxConnections)
return getConnectionNow();
try
wait(1000);
catch (InterruptedException e)
// ignore
while (System.currentTimeMillis() <= max);
throw new SQLException("Login timeout", "08001", 8001);
您的示例中最昂贵的操作之一是创建连接。如您所见,方法getConnection()
具有锁同步(this),因此只有一个线程可以同时创建连接,所有其他线程都在等待。
我相信内置的 h2 连接池非常简单。如果你想拥有高性能的连接池,你可以看看 C3P0 或 BoneCP。
【讨论】:
以上是关于用 H2 数据库理解 JdbcConnectionPool的主要内容,如果未能解决你的问题,请参考以下文章
如何将 NewProxyConnection 类型转换为 AS400JDBCConnection
如何使用 HSQLDB API 的 org.hsqldb.jdbc.JDBCConnection 类