Richard, Radu,
READ COMMITTED and REPEATABLE READ only affect plain SELECTs, not SELECT ... FOR UPDATE.
In the 4.1.8 execution:
"
1.mysql> select * from T where C = 42 for update;
2.mysql> select * from T where C = 42 for update;
-- The above select doesn't block now.
1.mysql> insert into T set C = 42;
-- The above insert blocks.
2.mysql> insert into T set C = 42;
ERROR 1213: Deadlock found when trying to get lock; Try restarting transaction
"
the explanation is that the X lock on the 'gap' set in SELECT ... FOR UPDATE is purely 'inhibitive'. It blocks inserts by other users to the gap. But it does not give the holder of the lock a permission to insert.
Why the inhibitiveness: if we have three index records:
aab <first gap> aba <second gap> acc
there are two gaps there. Suppose user 1 locks the first gap, and user 2 locks the second gap.
But if 'aba' is delete-marked, purge can remove it, and these two gaps merge. Then BOTH user 1 and user 2 have an exclusive lock on the same gap. This explains why a lock on gap does not give a user a permission to insert. There must not be locks by OTHER users on the gap, only then is the insert allowed.
Best regards,
Heikki
Oracle Corp./Innobase Oy
InnoDB - transactions, row level locking, and foreign keys for MySQL
InnoDB Hot Backup - a hot backup tool for InnoDB which also backs up MyISAM tables
http://www.innodb.com/order.php