数据库更新 - 长时间运行操作失败

时间:2011-11-23 08:06:48

标签: mysql performance hibernate jpa transactions

我正在使用hibernate将对象放入DB中。 DB是MYSQL社区版。 整个更新都会进入交易。

执行此操作的代码是:

  

getHibernateTemplate()saveOrUpdate(顺序);

当订单很小时没有问题,但是当我测试具有接近1 000 000个项目的场景时,我遇到了这个问题:

11-22@12:56:48 DEBUG PersistOrderServiceImpl [flow.ottoImportOrderPlacementInboundFlow.1] - saving order instance::
[Order [orderId=080661, vatOrderNumber=SODE000001, orderDate=Tue Nov 08 10:12:37 CET 2011, shippingMethod=STANDARD, ....

11-22@13:02:12 ERROR JDBCTransaction [flow.ottoImportOrderPlacementInboundFlow.1] - JDBC rollback failed
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
.....
....
11-22@13:02:12 ERROR TransactionInterceptor [flow.ottoImportOrderPlacementInboundFlow.1] - Application exception overridden by rollback exception
java.lang.NullPointerException
        at com.mysql.jdbc.Field.setConnection(Field.java:972)
        at com.mysql.jdbc.StatementImpl.getGeneratedKeysInternal(StatementImpl.java:1912)
        at com.mysql.jdbc.StatementImpl.getGeneratedKeysInternal(StatementImpl.java:1905)
        at com.mysql.jdbc.StatementImpl.getGeneratedKeys(StatementImpl.java:1885)
        at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.getGeneratedKeys(NewProxyPreparedStatement.java:1749)
        at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:97)
        at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:57)
......
...... 

似乎问题在大约5分24秒或324秒后出现。

我在MySQL日志中找不到任何关于它的内容。

它似乎与内存无关,因为当我降低内存时异常是不同的:

java.lang.OutOfMemoryError: GC overhead limit exceeded 

我不知道这是否是MySQL的Hibernate中的某种错误,或者是某些限制更新/连接/事务可以运行的时间的设置。

我在MySQL文档或Hibernate设置中找不到任何相关内容。

感谢您在调试或解决此问题方面提供的任何帮助。

已解决:问题出现在我的tomcat lib中的文件c3p0.properties中。 它包含:c3p0.unreturnedConnectionTimeout = 300,这或多或少是我得到错误的时间。删除后,更新通过,没问题。

1 个答案:

答案 0 :(得分:2)

数据库连接池配置了超时值。一旦事务开始(从池中借用了连接)并且在此超时值之前未完成(不释放与池的连接),则连接将由数据库连接池关闭(标记为已放弃)。当hibernate尝试提交事务时(请注意,hibernate无法知道连接是否已在此处关闭),驱动程序会出现异常。尝试将您的交易分解为更小的交易(批量提交项目)。将所有订单插入数据库后,插入Order对象。但是,您的应用程序代码应该处理批量提交失败以及之后的回滚逻辑。