*** SCENARIO 1 - non-existent row in middle of table *** Table contains 10 and 15, and we do FOR UPDATE on 13 and then try INSERT CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB; INSERT INTO test VALUES (10); INSERT INTO test VALUES (15); Transaction A: START TRANSACTION; SELECT * FROM test WHERE id=13 FOR UPDATE; We get: Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Transaction B: START TRANSACTION; SELECT * FROM test WHERE id=13 FOR UPDATE; We get: Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Back to Transaction A: INSERT INTO test VALUES (13); We get: Query OK, 1 rows affected (0.00 sec) Back to Transaction B: INSERT INTO test VALUES (13); We get: This one waits until Transaction A finishes and then reports duplicate key error. Rollback both transactions. Not ideal - should FOR UPDATE not prevent other people writing to that ID? If this is deliberate because the row does not exist, then how does one prevent an INSERT? Currently, there is absolutely no way to do it and I am of believe that FOR UPDATE should prevent an INSERT of a new row in that ID location. *** SCENARIO 2 - non-existent row at beginning of table *** Table contains 10 and 15, and we do FOR UPDATE on 1 and then try INSERT Using same tables above Transaction A: START TRANSACTION; SELECT * FROM test WHERE id=13 FOR UPDATE; We get: Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Transaction B: START TRANSACTION; SELECT * FROM test WHERE id=13 FOR UPDATE; We get: Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Back to Transaction A: INSERT INTO test VALUES (13); We get: This actually hangs... Back to Transaction B: INSERT INTO test VALUES (13); We get: ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction Rollback both transactions. This is the deadlock information: ------------------------ LATEST DETECTED DEADLOCK ------------------------ 111114 16:45:20 *** (1) TRANSACTION: TRANSACTION 1C05F8, ACTIVE 19 sec, process no 25006, OS thread id 1233885504 inserting mysql tables in use 1, locked 1 LOCK WAIT 3 lock struct(s), heap size 376, 2 row lock(s) MySQL thread id 247200, query id 2426549 localhost root update insert into test values(1, 10) *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 0 page no 439 n bits 80 index `PRIMARY` of table `eagleeye`.`test` trx id 1C05F8 lock_mode X locks gap before rec insert intention waiting Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0 0: len 4; hex 00000063; asc c;; 1: len 6; hex 0000001be954; asc T;; 2: len 7; hex f1000001470110; asc G ;; 3: len 4; hex 0000000a; asc ;; *** (2) TRANSACTION: TRANSACTION 1C061E, ACTIVE 11 sec, process no 25006, OS thread id 1233619264 inserting mysql tables in use 1, locked 1 3 lock struct(s), heap size 376, 2 row lock(s) MySQL thread id 247209, query id 2426581 localhost root update insert into test values (1, 10) *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 0 page no 439 n bits 80 index `PRIMARY` of table `eagleeye`.`test` trx id 1C061E lock_mode X locks gap before rec Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0 0: len 4; hex 00000063; asc c;; 1: len 6; hex 0000001be954; asc T;; 2: len 7; hex f1000001470110; asc G ;; 3: len 4; hex 0000000a; asc ;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 0 page no 439 n bits 80 index `PRIMARY` of table `eagleeye`.`test` trx id 1C061E lock_mode X locks gap before rec insert intention waiting Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0 0: len 4; hex 00000063; asc c;; 1: len 6; hex 0000001be954; asc T;; 2: len 7; hex f1000001470110; asc G ;; 3: len 4; hex 0000000a; asc ;; *** WE ROLL BACK TRANSACTION (2) *** SCENARIO 3 - non-existent row at end of table *** Table contains 10 and 15, and we do FOR UPDATE on 1000 and then try INSERT Using same tables above Transaction A: START TRANSACTION; SELECT * FROM test WHERE id=1000 FOR UPDATE; We get: Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Transaction B: START TRANSACTION; SELECT * FROM test WHERE id=1000 FOR UPDATE; We get: Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Back to Transaction A: INSERT INTO test VALUES (1000); We get: This actually hangs... Back to Transaction B: INSERT INTO test VALUES (1000); We get: ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction Rollback both transactions. This is the deadlock information: ------------------------ LATEST DETECTED DEADLOCK ------------------------ 111114 16:44:20 *** (1) TRANSACTION: TRANSACTION 1C05A8, ACTIVE 18 sec, process no 25006, OS thread id 1233885504 inserting mysql tables in use 1, locked 1 LOCK WAIT 3 lock struct(s), heap size 376, 2 row lock(s) MySQL thread id 247200, query id 2426395 localhost root update insert into test values (5000, 0) *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 0 page no 439 n bits 80 index `PRIMARY` of table `eagleeye`.`test` trx id 1C05A8 lock_mode X insert intention waiting Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 0: len 8; hex 73757072656d756d; asc supremum;; *** (2) TRANSACTION: TRANSACTION 1C05B5, ACTIVE 10 sec, process no 25006, OS thread id 1233619264 inserting mysql tables in use 1, locked 1 3 lock struct(s), heap size 376, 2 row lock(s) MySQL thread id 247209, query id 2426427 localhost root update insert into test values (5000, 0) *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 0 page no 439 n bits 80 index `PRIMARY` of table `eagleeye`.`test` trx id 1C05B5 lock_mode X Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 0: len 8; hex 73757072656d756d; asc supremum;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 0 page no 439 n bits 80 index `PRIMARY` of table `eagleeye`.`test` trx id 1C05B5 lock_mode X insert intention waiting Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 0: len 8; hex 73757072656d756d; asc supremum;; *** WE ROLL BACK TRANSACTION (2)