更新sql上MYSQL锁等待超时错误

时间:2015-08-06 04:49:00

标签: java mysql timeout deadlock

订单商品表
  order_item_id
order_id
数量
unit_price
shipping_price
business_id
workflow_id
delivery_id
item_id

订单表
billing_address_id
shipping_address_id
payment_mode
total_price
shipping_price
customer_id

UPDATE `order_items` t1 INNER JOIN Orders t2 ON t2.order_id = t1.order_id SET t1.workflow_id = ?  WHERE t1.order_item_id = ? and t2.order_id = ? and t2.customer_id = ? and t1.delivery_id = ? 

UPDATE `order_items` t1 SET t1.workflow_id = ?
           WHERE t1.order_item_id = ? and t1.business_id = ? and t1.delivery_id = ?

UPDATE `order_items` t1 INNER JOIN Orders t2 ON t2.order_id = t1.order_id SET t1.workflow_id = ? WHERE t1.order_item_id = ?  and t2.order_id = ? and t1.delivery_id = ?"

这些查询是在我的java rest服务的不同场景中触发的。 (在任何时间点,将只使用一个查询)。 以前我没有在我的更新sql中使用内连接,它运行良好。

现在,在我修改了查询之后,它会抛出以下异常并且查询被卡住并且不会返回一分钟。

   java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:996)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3887)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3823)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582)

更新

发生这种情况是因为我们忘了在finally块中再次将自动提交模式设置为true。之后我们没有看到这个错误。

2 个答案:

答案 0 :(得分:0)

Point1:您不应该使用join in application更新查询,而是获取主键,然后根据主键更新表。

Point2:使用索引显示您的表结构,您可以通过“show create table mytable”命令获取详细信息,以便检查您的更新查询是否已优化。

Point3:如果由于任何特定原因仍希望基于连接进行更新,并且您的查询也已优化,则需要更改wait_timeout变量。因此,请检查服务器上此变量中设置的值。你可以通过以下命令检查 -

SHOW GLOBAL VARIABLES LIKE 'wait_timeout';

答案 1 :(得分:0)

运行UPDATE查询之前的一件好事就是运行相同的SELECT。即

SELECT * FROM `order_items` t1 INNER JOIN Orders t2 ON t2.order_id = t1.order_id SET t1.workflow_id = ?  WHERE t1.order_item_id = ? and t2.order_id = ? and t2.customer_id = ? and t1.delivery_id = ? 

为了确保您正在更新正确的行。 您还可以对该查询运行EXPLAIN,以了解它对您的数据库的复杂程度。