java.sql.SQLException:超出锁定等待超时;尝试在MYSQL中重启事务异常

时间:2012-10-04 11:52:13

标签: java mysql sql struts

我在 MYSQL 中使用一个表名“test”,它在事务T1期间锁定,将在20分钟内完成。当我在这20分钟内通过另一个事务T2更新此表时。我得到一个例外: -

11:58:38,584 ERROR [STDERR] java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
11:58:38,584 ERROR [STDERR]     at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2928)
11:58:38,584 ERROR [STDERR]     at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1571)
11:58:38,584 ERROR [STDERR]     at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1124)
11:58:38,584 ERROR [STDERR]     at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:676)

请提供解决方案,如何在不收到此异常的情况下执行此事务T2?

在mysql数据库中更新 innodb_lock_wait_timeout 的值是否正确以解决此异常。我期待着为这个问题找到任何有用的解决方案。

2 个答案:

答案 0 :(得分:7)

更新innodb_lock_wait_timeout的值是不是解决此问题的正确方法。对于初学者来说,听起来你需要将它更新为20分钟,这将是荒谬的。

innodb_lock_wait_timeout的默认值为50秒 - 这是T2在放弃之前等待访问T1锁定的表的时间长度(并导致您看到的异常)。

你的T2交易在做什么?如果它只执行读取(即不写入表“test”),那么可以将数据库的隔离级别更改为“read uncommitted”,以便T2可以读取未提交的数据。但是,IMO这是你应该避免的黑客攻击。

相反,您应该考虑您的设计/实施。让一个打开的事务并持有20分钟的行锁是在多线程环境(例如webapp)中遇到麻烦。

您的归档活动(需要20分钟)是否必须在一次交易中?解决这个问题的一个显而易见的方法是在每个语句之后提交或将其分解为更合理大小的事务。

答案 1 :(得分:-11)

重启本地mysql以避免此类问题