如何避免锁定等待超时超出异常。?

Posted

技术标签:

【中文标题】如何避免锁定等待超时超出异常。?【英文标题】: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。

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

【问题讨论】:

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

以下是一些建议:

    锁定等待超时”通常发生在事务正在等待更新已被其他事务锁定的数据行时。 大多数时候,问题出在数据库端。可能的原因可能是表设计不当、数据量大、约束等。 请查看此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 *** 文章中:

@Transactional(propagation = Propagation.REQUIRES_NEW)

【讨论】:

【参考方案6】:

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

【讨论】:

【参考方案7】:

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

【讨论】:

以上是关于如何避免锁定等待超时超出异常。?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有超时的情况下锁定 Ibm Db2 中的更新行?

为啥在尝试更新 MySQL 条目时出现“超过锁定等待超时”错误?

使用模型工厂的 MySQL 锁定等待超时

“错误代码:1205。超过锁定等待超时;尝试重新启动事务”删除事件

超过锁定等待超时;尝试重新启动交易[关闭]

Laravel - DatabaseTransactions - 超过锁定等待超时