Skip to content

Instantly share code, notes, and snippets.

@roustem
Last active February 19, 2023 23:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save roustem/db2398aa38be0cc88364 to your computer and use it in GitHub Desktop.
Save roustem/db2398aa38be0cc88364 to your computer and use it in GitHub Desktop.
MySQL Foreign Keys Deadlock
--
-- This example shows how bad MySQL is when handling foreign key locks.
-- Deadlock happens when multiple transactions are inserting child records
-- pointing to the same parent and then try to update the parent record.
--
-- The solution is to always try to update the parent record first
-- but it could be hard to track the when database schema is more complex.
--
-- Based on: https://bugs.mysql.com/bug.php?id=48652
--
-- 1. Setup
set session transaction isolation level read committed;
set autocommit = 0;
CREATE TABLE parents (
id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
counter int NOT NULL DEFAULT 0
);
CREATE TABLE children (
id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
parent_id BIGINT NOT NULL,
FOREIGN KEY (parent_id) REFERENCES parents(id) ON DELETE CASCADE
);
INSERT INTO parents (id, counter) VALUES (1, 0);
COMMIT;
-- 2. client A
set session transaction isolation level read committed;
set autocommit = 0;
INSERT INTO children (parent_id) VALUES(1);
-- 3. client B
set session transaction isolation level read committed;
set autocommit = 0;
INSERT INTO children (parent_id) VALUES(1);
UPDATE parents SET counter = counter + 1 WHERE id = 1;
-- 4. client A
UPDATE parents SET counter = counter + 1 WHERE id = 1;
-- BOOM! DEADLOCK!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment