4/14/2009

Hibernate运行报错:org.hibernate.TransactionException: JDBC rollback failed

现象:
系统刚刚部署好的当天,访问系统没有问题,运行一段时间后访问该系统便会报错:org.hibernate.TransactionException: JDBC rollback failed,这个时候再重启tomcat一切又都好用了。也可以通过下面的方法测试,重新启动tomcat,一切好用,运行一段时间后,继续报错…服务器控制台提示:关闭的连接。
页面提示错误:

org.hibernate.TransactionException: JDBC rollback failed org.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:150) com.hostel.guest.Base.BaseDAO.save(BaseDAO.java:646) com.hostel.guest.Base.BaseLogDAO.savesysloginfo(BaseLogDAO.java:199) com.hostel.guest.servlet.AdminLogin.service(AdminLogin.java:99) javax.servlet.http.HttpServlet.service(HttpServlet.java:810) com.hostel.guest.servlet.MainServlet.service(MainServlet.java:586) javax.servlet.http.HttpServlet.service(HttpServlet.java:810) org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)控制台错误:

org.hibernate.TransactionException: JDBC rollback failed
at org.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:150)
at com.hostel.guest.Base.BaseDAO.save(BaseDAO.java:646)
at com.hostel.guest.Base.BaseLogDAO.savesysloginfo(BaseLogDAO.java:199)
at com.hostel.guest.servlet.AdminLogin.service(AdminLogin.java:99)
org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
at java.lang.Thread.run(Thread.java:595)
Caused by: java.sql.SQLException: 关闭的连接

网上的解决方法如下:
方法一:上网查了一下,有人说是数据库事务的原因,要把hibernate的autocommit设为false,我找了一下这个好像要在代码里面设置,而不能通过简单的设置Hibernate的配置文件来设置,就没有继续走这条路。后来想到可能是数据库连接池的原因。
方法二:在hibernate配置文件中加入对c3p0连接池的配置,同时将c3p0-0.8.4.5.jar拷贝到应用的lib文件夹下。这里说明一下,如果没有这个配置,hibernate默认使用其自身的数据库连接池。配置后则采用第三方的c3p0连接池。
使用c3p0连接池后确实没有问题了,但是我还是不明白为什么使用默认的连接池会有问题,如果哪位大哥清楚麻烦回复一下啊,谢谢!

把Hibernate的connection.autocommit设置为false

出现这个问题的原因
首先, 你的代码是从数据库读取用户信息, 不是写入数据. 所以不能使用事务和rollback方法.
第二, 当你更新和插入一条记录到数据库, 使用事务的时候, 关闭数据库的自动提交. 检查你的连接池是否正常.
第三, 当你有一个错误, 一定要关闭你的Hibernate连接. 当你捕获一个异常, 使用finally关闭hibernate Session或者数据库连接.
另外, 可能连接池已经用完.