【问题标题】:DB update - long running operation fails数据库更新 - 长时间运行的操作失败
【发布时间】:2012-01-04 13:13:28
【问题描述】:

我正在使用休眠将对象放入数据库。该数据库是 MYSQL 社区版。 整个更新运行到事务中。

执行它的代码是这样的:

getHibernateTemplate().saveOrUpdate(order);

订单量少时没有问题,但是当我测试了接近 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 库中的文件 c3p0.properties 中。 它包含: c3p0.unreturnedConnectionTimeout=300 这或多或少是我收到错误的时间。删除后更新通过,没问题。

【问题讨论】:

  • 所以您正在创建 100 万个 Order 对象并使用休眠模式持久化它们?你能发布休眠保存代码吗?
  • 不,我只创建一个包含 100 万件商品的订单。将代码发布到问题中。

标签: mysql performance hibernate jpa transactions


【解决方案1】:

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

【讨论】:

  • 我想我找到了原因 - 它在我的 tomcat 库中的文件 c3p0.properties 中。它包含: c3p0.unreturnedConnectionTimeout=300 这或多或少是我收到此错误后的时间。
  • 删除文件后,问题不再存在。所以你是对的,这是池化问题。谢谢!
  • 您应该小心,因为删除超时条目可能会导致一些不良影响。在将此称为永久修复之前,请阅读驱动程序和您正在使用的连接池的文档。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-27
  • 1970-01-01
  • 1970-01-01
  • 2017-10-30
  • 1970-01-01
相关资源
最近更新 更多