hibernate 执行原生sql或存储过程数据库连接问题

最近项目出现个问题,就是tomcat跑一段时间就会假死,页面能打开但是无法登陆,经过定位发现是数据库连接池满了,因为我之前hibernate用得不多,所以就写了几个测试代码来验证下哪种情况导致的。数据库持久层用的hibernate,所以只有执行原生sql和存储过程时会手动获取连接,那么问题应该就是出现在这些地方,但是之前没有出现问题,为什么现在出问题了呢?还是先写验证测试先,项目获取数据库连接获取用了三种:

①、

ConnectionProvider cp = ((SessionFactoryImplementor) this.getSessionFactory()).getConnectionProvider();
Connection conn = cp.getConnection();

 

②、

Session session = this.getSessionFactory().openSession();
Connection conn = session.connection();

 

 

③、

Session session = this.getSessionFactory().getCurrentSession();
Connection conn = session.connection();

 经过测试发现:

①这种方式获得数据库连接后,如果不手动关闭则会一直占用,必须调用conn.close()或者cp.closeConnection(conn)手动释放数据库连接。

 

②这种方式获得的数据库连接,也必须要手动关闭,否则也是会一直占用,但是关闭数据库连接不是conn.close()而是session.close()

 

 

③这种方式获得的数据库连接,可以不需要手动关闭,在程序执行完成之后会自动释放数据库连接

 

之前跑得正常的程序为什么这几天出现为问题了呢,然后看了一下最近的svn提交版本,发现打开了一个定时器,每天调用存储过程一次,这里却未关闭数据库连接。立马修正,测试,搞掂。

 

后来想想之前就好好的 为啥这里会有问题呢?对比了下代码原来这里用得是openSession而其他地方用的是getCurrentSession,然后google了下getCurrentSession和openSession的区别发现:

1 getCurrentSession创建的session会和绑定到当前线程,而openSession不会。

2 getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭。

 

怪不得之前不会占满数据库连接池,原来是用得是getCurrentSession,即使不手动关闭也没关系。

又长点知识,特此mark一下。

猜你喜欢

转载自ducaijun.iteye.com/blog/2007616
今日推荐