无法关闭 JDBC 资源!
我们正在使用 Oracle DB 运行一个 websphere 商务网站,并面临数据库连接不足的问题。 我们使用 JDBCHelper 单例来获取准备好的语句并建立连接。
public static JDBCHelper getJDBCHelper() {
if (theObject == null){
theObject = new JDBCHelper();
}
return theObject;
}
public void closeResources(Connection con, PreparedStatement pstmt, ResultSet rs){
try{
if(rs!=null){ rs.close();}
}catch(SQLException e){
logger.info("Exception closing the resultset");
}try{
if(pstmt!=null) { pstmt.close(); }
}catch(SQLException e){
logger.info("Exception closing the preparedstatement");
}try{
if(con!=null){ con.close(); }
}catch(SQLException e){
logger.info("Exception closing the connection");
}
}
然而,当我们尝试使用 prepStmt.getConnection() 获取连接以在执行后传递给关闭资源时,它会引发 sql 异常。知道为什么吗?执行后连接是否立即关闭?那么我们使用单例的JDBCHelper是不是有什么问题呢?
编辑
制作准备好的语句、执行并关闭连接的代码部分
PreparedStatement pstmt = jdbcHelper.getPreparedStatement(query);
try{
//rest of the code
int brs = pstmt.executeUpdate();
}
finally{
try {
jdbcHelper.closeResources(pstmt.getConnection(),pstmt);
} catch (SQLException e1) {
logger.logp(Level.SEVERE,CLASS_NAME,methodName,"In the finally block - Could not close connection", e1);
}
}
We are running a websphere commerce site with an oracle DB and facing an issue where we are running out of db connections.
We are using a JDBCHelper singleton for getting the prepared statements and cosing the connections.
public static JDBCHelper getJDBCHelper() {
if (theObject == null){
theObject = new JDBCHelper();
}
return theObject;
}
public void closeResources(Connection con, PreparedStatement pstmt, ResultSet rs){
try{
if(rs!=null){ rs.close();}
}catch(SQLException e){
logger.info("Exception closing the resultset");
}try{
if(pstmt!=null) { pstmt.close(); }
}catch(SQLException e){
logger.info("Exception closing the preparedstatement");
}try{
if(con!=null){ con.close(); }
}catch(SQLException e){
logger.info("Exception closing the connection");
}
}
However when we try getting the connection using a prepStmt.getConnection() for passing to the close resources after execution it throws an sql exception. Any idea why? Does the connection get closed immediately after execution? And is there something wrong in our use of the singleton JDBCHelper?
EDIT
Part of the code which makes the prepared statement,executes and closes the connection
PreparedStatement pstmt = jdbcHelper.getPreparedStatement(query);
try{
//rest of the code
int brs = pstmt.executeUpdate();
}
finally{
try {
jdbcHelper.closeResources(pstmt.getConnection(),pstmt);
} catch (SQLException e1) {
logger.logp(Level.SEVERE,CLASS_NAME,methodName,"In the finally block - Could not close connection", e1);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的连接很可能来自池,关闭它实际上会将连接返回到池(在幕后)。我认为发布获取连接、使用它并通过 JDBCHelper 关闭它的代码会更有用。
关于。你的单身人士,我不确定你为什么要使用它,因为它似乎没有任何东西保证它是单身人士。查看 Apache Commons DbUtils,它可以完成此类工作以及更多功能。
Your connection will most likely come from a pool, and closing it actually will return the connection to the pool (under the covers). I think posting the code which gets the connection, uses it and closes it via JDBCHelper will be of more use.
Re. your singleton, I'm not sure why you're using this, since it doesn't appear to have anything to warrant it being a singleton. Check out Apache Commons DbUtils which does this sort of stuff and more besides.
该代码似乎仅针对单线程操作编写,因为它缺少任何同步代码。例如,
getJdbcHelper()
方法可能会创建两个JdbcHelper
。如果我没记错的话,甚至不能保证第二个线程会在主线程创建对象很久之后看到它。尽管它们通常会这样做,但由于 JVM 运行的架构不同。如果您在 Web 服务器内运行它,您可能会遇到竞争问题,即两个线程同时修改您的连接。除非你推出了自己的连接池或其他东西。
Brian 是对的,使用免费提供的库之一可以为您解决这个(困难)问题。
This code seems to be written for single threaded operation only, as it's lacking any synchronisation code. The
getJdbcHelper()
method for instance is likely to create twoJdbcHelper
s. If I'm not mistaken there's even no guarantee that a second thread will see theObject, long after a primary thread has created it. Although they usually will, by virtue of the architecture the JVM runs on.If you're running this inside a web server you're likely to be running into race issues, where two threads are modifying your connection at the same time. Unless you rolled your own connection pool or something.
Brian is right, use one of the freely available libraries that solve this (hard) problem for you.