我正确使用Java PooledConnections吗?

时间:2010-03-01 02:23:09

标签: java mysql database multithreading

我想使用与Java的池连接(因为每个线程创建一个连接的成本很高)所以我使用的是MysqlConnectionPoolDataSource()对象。我在线程中持久化我的数据源。所以,我只在整个应用程序中使用一个数据源,如下所示:

  startRegistry();    // creates an RMI registry for MySQL
  MysqlConnectionPoolDataSource dataSource = new MysqlConnectionPoolDataSource();
  dataSource.setUser("username");
  dataSource.setPassword("password");
  dataSource.setServerName("serverIP");
  dataSource.setPort(3306);
  dataSource.setDatabaseName("dbname");

  InitialContext context = createContext();   // Creates a context
  context.rebind("MySQLDS", dataSource);

现在我创建了自己的数据源,我在每个单独的线程中执行以下操作:

  PooledConnection connect = dataSource.getPooledConnection();
  Connection sqlConnection = connect.getConnection();

  Statement state = sqlConnection.createStatement();

  ResultSet result = state.executeQuery("select * from someTable");
  // Continue processing results

我想我感到困惑的是打电话给dataSource.getPooledConnection(); 这真的是一个汇集连接吗?这个线程安全吗? 我注意到PooledConnection有像notify()和wait()这样的方法......这意味着我不认为它正在做我认为它正在做的事情......

此外,何时以及如何释放连接?

我想知道滚动自己是否更有利,因为我对所有事情都比较熟悉,但在这种情况下我真的不想重新发明轮子:)。

非常感谢

1 个答案:

答案 0 :(得分:15)

这不是正确的方法。数据源需要由运行应用程序的任何容器管理。MysqlConnectionPoolDataSource 连接池。它只是javax.sql.DataSource接口的具体实现。您通常在JNDI上下文中定义它并从那里获取它。 MySQL本身也在their documentation中明确说明了这一点。

现在,如何使用它取决于应用程序的目的。如果它是Web应用程序,那么您需要引用相关servletcontainer / appserver的JNDI资源文档。如果它是例如Tomcat,那么你可以找到它here。如果您正在运行客户端应用程序 - 我会高度质疑连接池的价值 - 那么您需要寻找一个连接池框架,它可以利用MySQL提供的连接池数据源,例如C3P0

您发布的代码的另一个问题是PooledConnection#getConnection()将返回底层连接,因此是池连接。在它上面调用close将不会返回到池的连接,但只是关闭它。该池必须每次都创建一个新连接。

然后是线程安全故事,这取决于所讨论的真正的连接池框架。 C3P0已经证明了它多年来的强大功能,只要您按照标准习惯编写JDBC代码,即使用 JDBC接口并获取,您就不用担心它了。在尽可能短的范围内关闭所有资源(ConnectionStatementResultSet)。