精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-04-19
1 使用连接池 2 使用了spring的ioc,即DAO是单例的 提出这个问题是由于我们系统中的实际出现的状况 由于开发人员众多,素质参差不齐,开发时间紧迫, 出现了大量的不符合规范的代码以及错误代码. 常见的就是 在关闭链接的时候没有关闭链接的创建的所有的Statement (关闭了部分,但不是所有) 所以想和 大家探讨一下该如何在代码层次实现关闭数据库链接时,自动关闭由该链接创建的所有的Statement. 我的思路是这样的 将"当前线程+当前链接"创建的所有Statement 放入一个ThreadLocal 对象内. 当关闭链接时, 从ThreadLocal 对象取出 所有的 Statement ,逐个关闭. 不知道这样的思路是否可行. 下面附上代码: 为了阅读方便没有写出全部的创建Statement的方法 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; } } 在dao内的getConnection时 可以这么写 protected final Connection getConnection(){ Connection conn=DataSourceUtils.getConnection(getDataSource()); ConnectionUtils.initStatementMap(conn); return conn; } 关闭Connection时 可以这么写 protected final void closeConnection(Connection conn) { ConnectionUtils.closeAllStatement(conn); DataSourceUtils.releaseConnection(conn, getDataSource()); } 要创建Statement时可以这么写 pstmt = ConnectionUtils.prepareStatement(conn,bufSql.toString()); 以上只是我的一些思路,虽然在本机测试是可以的,但是不知道到底实际上是否可行 还请看看 谢谢了 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-04-19
这种方法不在源头解决,我看以后维护可能比较麻烦。
源头上统一使用一些jdbcTemplete方法避免直接管理connection和statement不就可以了? |
|
返回顶楼 | |
发表时间:2007-04-19
楼上的有些高估我们的开发所采用的技术了
我们dao里就是要操作那些基本的 connection statement resultset 在这个前提下有什么办法呢 我也很无奈 如果想从源头解决问题 那就是所有开发人员提高个人职业修养和素质 否则什么都没用 |
|
返回顶楼 | |
发表时间:2007-04-19
使用jdbcTemplete是不错的办法,推广它的时间和培训时间应该不是难么难吧
|
|
返回顶楼 | |
发表时间:2007-04-19
其实这些我知道
但是现在的前提是 系统已经开发完成 一共有2000多个dao 都使用了传统的方式 在进行最小的重构前提下,我在顶楼里提出的那种思路和方案是否可行呢 |
|
返回顶楼 | |
发表时间:2007-04-19
自己实现一下 java.sql.Connection等接口,把原来的connection包装一下就可以了阿. |
|
返回顶楼 | |
发表时间:2007-04-19
装饰模式的经典场景.
另外好的连接池在回收Connection的时候会自动关闭ResultSet 和 Statement 的 |
|
返回顶楼 | |
发表时间:2007-04-20
codeutil 写道 自己实现一下 java.sql.Connection等接口,把原来的connection包装一下就可以了阿. 以楼主项目的情况来看,有那么多的dao类要进行最小范围的重构,这样的办法应该是不错的。 另外楼主的方法应该也可行,只是增加了些代码量 |
|
返回顶楼 | |
发表时间:2007-04-20
既然这样的话,我也觉得包装Connection,然后delegate到实际的Connection上,除了在prepareStatement,createStatement等方法上做一些处理,将Statement对象记录下来;等Connection.close()时,调用所有Statement.close()。
|
|
返回顶楼 | |
发表时间:2007-04-20
6楼正解
|
|
返回顶楼 | |