【问题标题】:How to Avoid Lock wait timeout exceeded exception.?如何避免锁定等待超时超出异常。?
【发布时间】:2012-12-07 15:16:30
【问题描述】:
    java.sql.SQLException: Lock wait timeout exceeded; try restarting tra
nsaction at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3558)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3490)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2109)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2648)
        at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.ja
va:2077)
        at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:
2228)
        at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:
208)
        at org.hibernate.loader.Loader.getResultSet(Loader.java:1812)
        at org.hibernate.loader.Loader.doQuery(Loader.java:697)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Lo
ader.java:259)
        at org.hibernate.loader.Loader.loadEntity(Loader.java:1885)
        ... 131 more

我在更新记录时收到重复的锁定超时异常。

我正在使用 Java Struts 2.1 Hibernate 配置。 使用的数据库是 MYSQL。

任何人都知道如何解决它..??

【问题讨论】:

  • 优化查询,或增加事务超时。使用show innodb status 检查发生了什么;
  • @SubinS 我没有在我的程序中使用自动提交,我认为我需要对代码持乐观态度。你能建议一些链接来帮助我设置 MySQL。我是这方面的初学者,所以需要一些帮助。我使用了“set innodb_lock_wait_timeout=100”,但是没有用。

标签: java mysql hibernate


【解决方案1】:

以下是一些建议:

  1. 锁定等待超时”通常发生在事务正在等待更新已被其他事务锁定的数据行时。
  2. 大多数时候,问题出在数据库端。可能的原因可能是表设计不当、数据量大、约束等。
  3. 请查看此elaborate answer

【讨论】:

  • 解决这个问题的一种方法是简单地重启你的 MySQL 服务器
  • 但如果问题出在您的表格设计和大数据等方面。问题会再次出现。
【解决方案2】:

确保数据库表使用 InnoDB 存储引擎和 READ-COMMITTED 事务隔离级别。

您可以在mysql控制台上通过SELECT @@GLOBAL.tx_isolation, @@tx_isolation;查看。

如果它没有被设置为 READ-COMMITTED 那么你必须设置它。在设置之前请确保您在 mysql 中具有 SUPER 权限。

您可以向http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html寻求帮助。

通过设置这个我认为你的问题会得到解决。

谢谢。

【讨论】:

  • 此解决方案有一些重要的副作用,开发人员必须注意这些副作用。但它可以帮助调试死锁背后的真正问题。
  • 谢谢,但您没有提到这有助于解决该异常?
  • 我试过 SET GLOBAL transaction_isolation='READ-COMMITTED';并给了我错误我会谷歌它加上我也改变了这个 innodb_lock_wait_timeout 50 到 300 秒
【解决方案3】:

(恭敬地忽略数据库特定的答案)

当使用正式的CRUD 模式并通过 Singleton 类引导所有数据库流量时,您仍然会遇到线程锁定。这通常是由于您自己、大学和 Hibernate 团队之间的疏忽而发生的。因此,检查自己的代码是否有错误是最快的——特别注意 hibernate 的核心规则。

通常CRUD 接口具有public 'Create'、'Read'、'Update' 和 'Delete' 方法,它们共享通用的private 方法。这是为DRY 最佳实践完成的。然而,在这样做的过程中,这些方法将在大多数情况下完美运行,但并非所有时间。

那么,如何测试和解决线程锁定问题?

确保:

  • session.save(myObj)动作先检查PK的唯一性
  • 所有uniqueResult() 查询确实返回 1 个结果,并且;

    (重要!)关注以下测试用例:

    • 引入 PK 副本
    • 更新/读取/删除不存在的记录/条目/行

最后,使用@AfterSuite (TestNG) 删除所有表条目。任何不充分的实现都会在上述操作上产生另一个线程锁......否则,你就是黄金。

【讨论】:

  • 检查PK的唯一性如何确保没有线程阻塞
  • Hibernate 是一个用于将域模型映射到关系数据库的框架。它是一个忠实的信使,相信你的命令。就是这样。所以你这个消费者必须给它明智的指示。就像,不是创建相同的记录,而是更新现有的记录。
【解决方案4】:

检查您的 where 子句是否已优化......即使用主键和/或索引

【讨论】:

    【解决方案5】:

    这也可能是由于以下注释的误用造成的,例如this StackOverflow 文章中:

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    

    【讨论】:

      【解决方案6】:

      如果以上所有方法都不起作用,请检查 mysql 日志中的错误消息。如果提到日志文件的大小,需要在配置中增加,重启mysql服务器。

      【讨论】:

        【解决方案7】:

        删除@Transactional(propagation = Propagation.REQUIRES_NEW) 并检查。它会工作

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-12-11
          • 2018-06-01
          • 2016-12-16
          • 2011-01-07
          • 1970-01-01
          • 2021-09-01
          • 2019-11-20
          • 2017-02-01
          相关资源
          最近更新 更多