首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

从Session中获取Connection急需注意的

2012-10-30 
从Session中获取Connection需要注意的虽然不推荐从Session中获取connection,但是偶尔会出现一些特殊情况不

从Session中获取Connection需要注意的
虽然不推荐从Session中获取connection,但是偶尔会出现一些特殊情况不得以这样做。

接下来的问题就是:使用后的session/connection如何处理?

1.close connection
    相信大多数人的第一返回会是这样,关闭连接,这是非常错误的(没来得及看官方文档,自己做了下测试)
            <property name="initialSize" value="1" />
        <property name="maxActive" value="1" />
        <property name="maxIdle" value="1" />
        <property name="minIdle" value="1" />
</bean>

/**多线程测试关闭连接*/public static void closeTest() throws SQLException{Session session = Test.getSession();Connection conn = null;PreparedStatement pst = null;try{conn = session.connection();pst = conn.prepareStatement(sql);pst.executeQuery();}catch(Exception e){e.printStackTrace();}finally{conn.close();pst.close();}}

我本来是开的4个线程分别去执行这个方法20次,结果刚到第二次的时候,连接池便抛异常:
Timeout waiting for idle object(获取连接超时)。甚至后来只开一个线程也不行。

这里很奇怪,从连接池中取出来的connection不是已经经过包装了吗?在close()的时候会自动将连接放回连接池!?
我打印conn.getClass() 得到的是一个$Proxy,父类java.lang.reflect.Proxy
而从直接连接池(BasicDataSource)中取出来的是org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper
当然,也不能断定从session取出来的connection的close方法没有(试图)放入连接池,但事实是它的确没有正确归还。
而开四个线程同时跑以下代码没有一点问题,这个实验有点废....
public static void poolTest() throws SQLException{getConnection().close();}

(我打算用javasisst把从session中取出来的connection的close方法打印出来,实在找到其它方法如看动态代理的源代码,此处待续...)

2.Session.close();
将上面测试代码换成
public static void closeSessionTest() throws SQLException{Session session = Test.getSession();Connection conn = null;PreparedStatement pst = null;try{conn = session.connection();pst = conn.prepareStatement(sql);pst.executeQuery();}catch(Exception e){e.printStackTrace();}finally{session.close();if(pst != null){pst.close();}}}

ok!运行阶段没有异常。运行数速度也很快.!
分析见下一测试。

3.Session.disconnect();
测试代码
public static void closeSessionTest() throws SQLException{Session session = Test.getSession();Connection conn = null;PreparedStatement pst = null;try{conn = session.connection();pst = conn.prepareStatement(sql);pst.executeQuery();}catch(Exception e){e.printStackTrace();}finally{session.disconnect();if(pst != null){pst.close();}}}

运行结果正常,速度也正常。

很明显,对于从session中取出connection千万不要close()
进一步看hibernate源码,session.close()与session.disconnect()中都有一个(正常)分支流程是
if ( rootSession == null ) {return jdbcContext.getConnectionManager().close();}

而这个方法调用的是一个cleanup()的方法,具体的源码以后补上,晚了. 1 楼 yzjdt 2012-05-10   的确用close有问题  刚用close没报错 但是居然在获取连接那里卡住了
找了半天 才看到楼主这篇文章 才恍然大悟  感谢楼主分享啊

热点排行