上周练习JDBC时,使用Druid和ThreadLocal来控制事务的开启、提交、回滚,后期使用时出现了connection holder is null的异常,一开始以为是因为事务长时间未提交,自动关闭连接,后来改变了配置依然不行。
该异常的出现是属于获取连接超时,从而找不到持有者,本来每次事务提交或回滚后都应该关闭连接,ThreadLocal中移除connection对象,后来发现我的ThreadLocal.remove()方法放的位置不准确。
一开始放到resultSet关闭的if里,导致没有使用resultSet时并没有移除ThreadLocal的connection,导致ThreadLocal里关闭的connection对象没有及时remove,下一次使用时没办法获取正常运行的connection。
错误代码
public static void close(Connection connection, Statement statement, ResultSet resultSet){
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(resultSet != null){
try {
resultSet.close();
THREAD_LOCAL.remove();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
改正后
public static void close(Connection connection, Statement statement, ResultSet resultSet){
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
THREAD_LOCAL.remove();
}