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

时间:2012-12-20 06:25:15

标签: java mysql hibernate

    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配置。 DB Used是MYSQL。

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

7 个答案:

答案 0 :(得分:14)

以下是一些建议:

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

答案 1 :(得分:5)

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

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

如果未将其设置为READ-COMMITTED,则必须进行设置。在设置之前确保你在mysql中拥有超级特权。

您可以从http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html获取帮助。

通过设置此项,我认为您的问题将得到解决。

谢谢。

答案 2 :(得分:3)

也可能是因为误用了以下注释,例如在this StackOverflow文章中:

@Transactional(propagation = Propagation.REQUIRES_NEW)

答案 3 :(得分:1)

(尊重DB特定答案)

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

通常,CRUD界面具有 public 'Create','Read','Update'和'Delete'方法,这些方法共享常见的私有方法。这是针对DRY最佳做法完成的。但是,这样做,这些方法大部分时间都可以完美运行,但不是一直都是。

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

<强>确保:

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

    (重要!)焦点测试案例:

    • 介绍PK重复
    • 更新/读取/删除不存在的记录/条目/行

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

删除@Transactional(propagation = Propagation.REQUIRES_NEW)并检查。它将起作用