我面临以下例外:
com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction我可以告诉您的是,我有多个线程并行地在相同的表上执行查询。但我不明白为什么会出现这种异常。因为如果一个查询锁定了一个表,那么另一个线程中的同一个查询(或同一表上的其他查询)将等待锁。为什么会造成死锁?
我用不同的话重复,我理解异常,但我不明白的是,一个查询正在等待其他查询,另一个查询应该执行,离开锁,等待查询可以获得锁,为什么是死锁?
如果有人想查看实际查询(这些查询以与此处打印的相同顺序的多个线程执行,则没有任何事务):
UPDATE daily_stats, account, campaign SET campaign_messages_cost = campaign_messages_cost + (IF(current_free_sms >= ?, campaign.campaign_cost, campaign.campaign_cost + (account.sms_charging_rate * ? ))), campaign_messages_delivered_count = campaign_messages_delivered_count + 1 WHERE daily_stats_id = ? AND campaign.id = ? AND daily_stats.account_id = account.id
update account a JOIN campaign b ON a.id = b.account_id set campaign_cost = IF(current_free_sms >= ?, campaign_cost, campaign_cost + (a.sms_charging_rate * ? )), delivered_count = delivered_count + ?, credit = IF(current_free_sms >= ?, credit, credit - (a.sms_charging_rate * ?)), current_free_sms = IF (current_free_sms >= ?, current_free_sms - ?, current_free_sms) where b.id = ?发布于 2013-04-04 12:26:32
MySQL将任何查询语句视为事务(至少在使用默认的InnoDB引擎时),但是如果@@autocommit变量设置为1(默认),则所有语句都会立即自动执行,从而有效地隐藏事务的发生。这可以解释“发现的死锁”错误,尽管没有开始/提交/回滚,尽管错误消息的“回滚”部分有点神秘,而且我以前没有看到过。
MySQL提出的处理死锁的方法是将查询构造为最小化问题的组合,此外还编写代码来处理这些问题--因为它们会出现在像您这样的软件中。我的方法很简单,但效率很高:睡500毫秒,然后再试一次。我很少看到超过两次连续的重试,在一个处理相当高负载的系统上(尽管在公司环境中)。
您还应该查看MySQL关于如何处理死锁的建议。
https://stackoverflow.com/questions/15683679
复制相似问题