我是否正确地关闭了此Oracle池连接?
我正在尝试在Java中为我的Web应用程序使用池连接。我使用的是Oracle数据库,这里是我的代码:我是否正确地关闭了此Oracle池连接?
public class DatabaseHandler
{
static private Connection m_database = null;
static private OracleConnectionPoolDataSource pooledSource = null;
/**
* Attempts to open an Oracle database located at the specified serverName and port.
* @param serverName Address of the server.
* @param portNumber Port to connect to.
* @param sid SID of the server.
* @param userName Username to login with.
* @param password Password to login with.
* @throws WebApplicationException with response code 500 Internal Server Error.
*/
static public void openDatabase(String userName, String password,String serverName,int portNumber, String sid)
throws WebApplicationException
{
try
{
// Load the JDBC driver
String driverName = "oracle.jdbc.driver.OracleDriver";
Class.forName(driverName);
// Create a connection to the database
String url = "jdbc:oracle:thin:@" + serverName + ":" + portNumber + ":" + sid;
pooledSource = new OracleConnectionPoolDataSource();
pooledSource.setUser(userName);
pooledSource.setURL(url);
pooledSource.setPassword(password);
m_database = pooledSource.getConnection();
}
catch (ClassNotFoundException e)
{
// Could not find the database driver
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
catch (SQLException e)
{
// Could not connect to the database
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
}
/**
* Attempts to execute the specified SQL query.
* @throws WebApplicationException with a response code of Bad Request
* if the query is invalid SQL.
*/
static public ResultSet makeQuery(String query) throws WebApplicationException
{
ResultSet rs = null;
if (m_database != null)
{
try
{
Statement stmt = m_database.createStatement();
rs = stmt.executeQuery(query);
}
catch (SQLException e)
{
// invalid query
System.out.println(query);
throw new WebApplicationException(Response.Status.BAD_REQUEST);
}
}
return rs;
}
/**
* Attempts to close the database.
* @throws WebApplicationException with a response code of 500 Server error
*/
static public void closeDatbase() throws WebApplicationException
{
try
{
m_database.close();
pooledSource.close();
}
catch(SQLException e)
{
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
}
}
我在Eclipse这样做的,我有一个警告,pooledSource.close()
已被弃用。我从来没有使用过连接池,我只是想确保我做的一切都正确。有没有更好的方法来关闭Oracle池化资源?
不推荐使用的方法意味着不应使用此方法。在未来的版本中,可以完全清除close()
方法。我建议删除pooledSource.close()
。
此外,我建议不要有一个Connection
和DataSource
的静态实例,因为您需要请求连接,并且不会在整个应用程序中保持活动状态。请务必首先关闭ResultSet
,然后再将Connection
和保证的关闭,方法是将其添加到finally
区块中。
- 连接必须关闭才能返回到池中。
- 始终在finally块中关闭连接。
- 永远不要把连接引用当作类成员 - 这是容易出错和糟糕的设计。尽可能晚地连接并尽快释放连接。把这样的东西当作集体成员是没有意义的。
- 关闭使用它们的连接。你的代码在这里再次出错。如果您忘记拨打
closeDatabase()
,说明您正在泄漏连接。
注意: 不要混淆关闭connection
这里关闭connection pool
。
因为在这里要求是正确和良好的连接处理一些代码:
public void doSomethingWithDb(Connection con, ...) {
boolean release = (con == null);
try {
con = PersistenceUtils.getConnection(con); //static helper return a new conenction from pool when provided con==null otherwise simply returns the given con
//do something
if(release) {
con.commit();
}
}
catch(SQLException e) {
//handle errors, i.e. calling con.rollback() but be sure to check for con!=null before. Again maybe null-safe static helper method here.
}
finally {
if(release && con!=null){
con.close();
}
}
}
我使用的连接,方法的参数,以便能够调用许多中一个数据块的交易这样的方法。但是您始终可以将null
作为Connection的第一个参数,并且该方法可以从您的池中获取连接。
当您在“DB-Method”中调用另一个“DB-Method”时,您只需提供与底层方法的连接 - 以便在一个事务中拥有所有内容。
正如您所看到的,正确的JDBC代码会生成许多样板代码。在第一步中,你可以通过实现像PersistenceUtils这样的实用程序类来减少它,它提供静态的空安全方法,如提交(Connection),回滚(Connection),getConnection(连接),关闭(Connection)... 因为你摆脱所有的空检查,你也可以包括日志记录或其他东西。
对于第一点,这是如何实现的? – 2011-06-08 15:16:22
@The Elite Gentleman在连接对象上调用close()。也许它也会在垃圾收集时(我不知道)检查是否返回池中,但是因为尽快将其返回池很重要,所以必须自己调用它。按照步骤2以正确的方式执行此操作 - 始终在finally块中关闭这些资源。 – 2011-06-08 15:28:48
感谢您的帮助,我已经应用了您在此提供的建议。 – 2011-06-08 16:59:38
因此,我不需要显式关闭池连接,它是为我处理的?我想这可能是这种情况,但我想100%肯定,所以我不放弃连接而不是关闭连接。 – 2011-06-08 14:48:40
您不需要关闭连接池。如果从池中获得连接,则“连接”属于连接池,因此关闭连接会将其自动返回到池中。 – 2011-06-08 14:50:38
谢谢你的详细解释。 – 2011-06-08 14:52:19