开发者

Handling innoDB deadlock

开发者 https://www.devze.com 2023-02-16 19:19 出处:网络
I\'ve been getting a Deadlock found when trying to get lock; try restarting transaction error on my InnoDB tables. Here is the query:

I've been getting a Deadlock found when trying to get lock; try restarting transaction error on my InnoDB tables. Here is the query:

UPDATE views 
SET visit_cnt = visit_cnt + 1 
WHERE visit_day = DATE(NOW()) 
AND article_id = '4838'

This query also trigge开发者_StackOverflow中文版rs this via ON UPDATE trigger:

UPDATE articles 
SET views = views + 1 
WHERE id = NEW.article.id

Here is how I tried to fixed it:

$attempts_left = 5;
do
{
    mysql_query ($query);

    // if we found a deadlock, we will try this query 4 more times   
    if (mysql_errno () == 1213) { // 1213 - deadlock error
        $deadlocked = true;
        $attempts_left --;
    }
    else{
        $deadlocked = false;
    }
}
while($deadlocked && $attempts_left > 0);

My question: is this the only way to handle a deadlock? I mean this is quite ugly and deadlocks happen time to time anyway. Is there any recommended way to fix deadlocks?


Here is good documentation about handling InnoDB deadlocks.

PS: I didn't have anything more to add so just gave you the link.


That's the proper way, as the documentation states:

Normally, you must write your applications so that they are always prepared to re-issue a transaction if it gets rolled back because of a deadlock.

If you want to reduce the occurrence of deadlocks, you must show us the tables DDL and indexes.


You may have to play some games with the Transaction Isolation/MVCC features

Option 1) You may want to surround the query in a begin commit block

BEGIN;

UPDATE views
SET visit_cnt = visit_cnt + 1
WHERE visit_day = DATE(NOW())
AND article_id = '4838';

< Any actions in the trigger would be part of the transaction >

COMMIT;

Option 2) You may want to disable autocommit for your session

SET autocommit = 0;

Option 3) Change the transaction isolation before launching the query to expose dirty reads

This one is a stretch !!!

SET tx_isolation = READ_COMMITTED;

or

SET tx_isolation = READ_UNCOMMITTED;

Give it a Try and let us all know !!!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号