前提条件:
1 使用连接池
2 使用了spring的ioc,即DAO是单例的
提出这个问题是由于我们系统中的实际出现的状况
由于开发人员众多,素质参差不齐,开发时间紧迫,
出现了大量的不符合规范的代码以及错误代码.
常见的就是 在关闭链接的时候没有关闭链接的创建的所有的Statement
(关闭了部分,但不是所有)
所以想和 大家探讨一下该如何在代码层次实现关闭数据库链接时,自动关闭由该链接创建的所有的Statement.
我的思路是这样的
将"当前线程+当前链接"创建的所有Statement 放入一个ThreadLocal 对象内.
当关闭链接时, 从ThreadLocal 对象取出 所有的 Statement ,逐个关闭.
不知道这样的思路是否可行.
下面附上代码:
为了阅读方便没有写出全部的创建Statement的方法
[code]
public class ConnectionUtils {
public static final ThreadLocal statementMap = new ThreadLocal();
public static void initStatementMap(Connection conn){
String key=String.valueOf(conn);
Map map=(Map)statementMap.get();
if (map==null){
map=Collections.synchronizedMap(new HashMap());
statementMap.set(map);
}
if (map.get(key)==null) {
map.put(key, new ArrayList());
}
}
public static void putStatement(Connection conn,Statement statement){
Map map=(Map)statementMap.get();
List list=(List)map.get(conn.toString());
list.add(statement);
}
public static void closeAllStatement(Connection conn){
Map map=(Map)statementMap.get();
List list=(List)map.get(conn.toString());
for (Iterator itor=list.iterator();itor.hasNext();){
Statement stm=(Statement)itor.next();
try {
stm.close();
} catch (SQLException e) {
}
}
}
public static Statement createStatement(Connection conn) throws SQLException{
Statement statement=conn.createStatement();
putStatement(conn,statement);
return statement;
}
public static CallableStatement prepareCall(Connection conn, String sql) throws SQLException {
CallableStatement statement=conn.prepareCall(sql);
putStatement(conn,statement);
return statement;
}
public static PreparedStatement prepareStatement(Connection conn, String sql) throws SQLException{
PreparedStatement statement= conn.prepareStatement(sql);
putStatement(conn,statement);
return statement;
}
}
[/code]
在dao内的getConnection时 可以这么写
[code]
protected final Connection getConnection(){
Connection conn=DataSourceUtils.getConnection(getDataSource());
ConnectionUtils.initStatementMap(conn);
return conn;
}
[/code]
关闭Connection时 可以这么写
[code]
protected final void closeConnection(Connection conn) {
ConnectionUtils.closeAllStatement(conn);
DataSourceUtils.releaseConnection(conn, getDataSource());
}
[/code]
要创建Statement时可以这么写
[code]
pstmt = ConnectionUtils.prepareStatement(conn,bufSql.toString());
[/code]
以上只是我的一些思路,虽然在本机测试是可以的,但是不知道到底实际上是否可行
还请看看 谢谢了
1 使用连接池
2 使用了spring的ioc,即DAO是单例的
提出这个问题是由于我们系统中的实际出现的状况
由于开发人员众多,素质参差不齐,开发时间紧迫,
出现了大量的不符合规范的代码以及错误代码.
常见的就是 在关闭链接的时候没有关闭链接的创建的所有的Statement
(关闭了部分,但不是所有)
所以想和 大家探讨一下该如何在代码层次实现关闭数据库链接时,自动关闭由该链接创建的所有的Statement.
我的思路是这样的
将"当前线程+当前链接"创建的所有Statement 放入一个ThreadLocal 对象内.
当关闭链接时, 从ThreadLocal 对象取出 所有的 Statement ,逐个关闭.
不知道这样的思路是否可行.
下面附上代码:
为了阅读方便没有写出全部的创建Statement的方法
[code]
public class ConnectionUtils {
public static final ThreadLocal statementMap = new ThreadLocal();
public static void initStatementMap(Connection conn){
String key=String.valueOf(conn);
Map map=(Map)statementMap.get();
if (map==null){
map=Collections.synchronizedMap(new HashMap());
statementMap.set(map);
}
if (map.get(key)==null) {
map.put(key, new ArrayList());
}
}
public static void putStatement(Connection conn,Statement statement){
Map map=(Map)statementMap.get();
List list=(List)map.get(conn.toString());
list.add(statement);
}
public static void closeAllStatement(Connection conn){
Map map=(Map)statementMap.get();
List list=(List)map.get(conn.toString());
for (Iterator itor=list.iterator();itor.hasNext();){
Statement stm=(Statement)itor.next();
try {
stm.close();
} catch (SQLException e) {
}
}
}
public static Statement createStatement(Connection conn) throws SQLException{
Statement statement=conn.createStatement();
putStatement(conn,statement);
return statement;
}
public static CallableStatement prepareCall(Connection conn, String sql) throws SQLException {
CallableStatement statement=conn.prepareCall(sql);
putStatement(conn,statement);
return statement;
}
public static PreparedStatement prepareStatement(Connection conn, String sql) throws SQLException{
PreparedStatement statement= conn.prepareStatement(sql);
putStatement(conn,statement);
return statement;
}
}
[/code]
在dao内的getConnection时 可以这么写
[code]
protected final Connection getConnection(){
Connection conn=DataSourceUtils.getConnection(getDataSource());
ConnectionUtils.initStatementMap(conn);
return conn;
}
[/code]
关闭Connection时 可以这么写
[code]
protected final void closeConnection(Connection conn) {
ConnectionUtils.closeAllStatement(conn);
DataSourceUtils.releaseConnection(conn, getDataSource());
}
[/code]
要创建Statement时可以这么写
[code]
pstmt = ConnectionUtils.prepareStatement(conn,bufSql.toString());
[/code]
以上只是我的一些思路,虽然在本机测试是可以的,但是不知道到底实际上是否可行
还请看看 谢谢了