I have two tables, one having a many-to-many relationship ( fooBarTable
with columns fooId
and barId
) and another InnoDB table fooCounterTable
with columns fooId
and counter
counting the occurences of fooId
in fooBarTable
.
When deleting all barId
's from fooBarTable
, I need to update the fooCounterTable
accordingly.
The first thing I tried was this:
UPDATE fooCounterTable SET counter = counter - 1
WHERE fooId IN (SELECT fooId FROM fooBarTable WHERE barId = 42 ORDER BY fooId);
But I got this error:
MySQL error (1205): Lock wait timeout exceeded; try restarting transaction
Updating the table when adding barId
's is working fine with this SQL statement:
INSERT INTO `fooCounterTable` (fooId, counter) VALUES (42,1), (100,1), (123,1)
ON DUPLICATE KEY UPDATE counter = counter + 1;
So I thought I'd do the same thing when decreasing the counter, even if it looks stupid to insert 0-Values, which should never happen:
INSERT INTO `fooCounterTable` (SELECT fooId, 0 FROM fooBarTable WHERE barId = 42 ORDER BY fooId)
ON DUPLICATE KEY UPDATE counter = counter - 1;'
This seems to work fine in most cases, but sometimes I get a deadlock:
MySQL error (1213): Deadlock found when trying to get lock; try restarting transaction
So I read about deadlocks and found out about SELECT ... FOR UPDATE
and I tried this:
START TRANSACTION;
SELECT fooId FROM fooCounterTable
WHERE fooId IN (SELECT fooId FROM fooBarTable WHERE barId = 42 ORDER BY fooId) FOR UPDATE;
UPDATE fooCounterTable SET counter = counter - 1
WHERE fooId IN (SELECT fooId FROM fooBarTable WHERE barId = 42 ORDER BY fooId);
COMMIT;
which resulted in:
MySQL error (2014): commands out of sync
Can anyone tell me how to resolve my problem?
Update
The last error (2014) occured, because I did not use and free the SELECT statement's results before executing the UPDATE statement, which is mandatory. I fixed that and I got rid of error 2014, but I still have deadlocks (error 1205) from time to time and I don't understand, why.
Do you know what fooID you have just deleted when firing this query?
If so seems like this would work...
UPDATE fooCounterTable SET counter =
(SELECT count(*) FROM fooBarTable WHERE fooId = 42)
WHERE fooID = 42
I wonder if you really need that counter table tho. If your indexes are set up properly there shouldn't be too much of a speed penalty to a more normalized approach.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.