1

我在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的值来解决这个异常是否正确。我期待为这个问题找到任何有用的解决方案。

4

2 回答 2

7

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

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

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

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

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

于 2012-10-04T11:57:41.573 回答
-10

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

于 2013-04-20T05:54:37.127 回答