hi,
I'm trying to understand why the following scenario behaves differently when dealing with MySQL to what I've seen when interacting with Oracle and MS SQL Server.
I have a table with two columns, 'show index' output is as follows:
Table, Non_unique, Key_name, Seq_in_index, Column_name, Collation, Cardinality, Sub_part, Packed, Null, Index_type, Comment, Index_comment
'lock12_5', '0', 'PRIMARY', '1', 'lockid', 'A', '11348', NULL, NULL, '', 'BTREE', '', ''
'lock12_5', '0', 'PRIMARY', '2', 'lockinfo', 'A', '11348', NULL, NULL, '', 'BTREE', '', ''
Using my first MySQL DB connection I'm executing (autocommit = 0) 'update lock12_5 set lockinfo='foo' where lockid='bar' and lockinfo='foo' and checking the return value. Whenever this query returns 0 and thus the referenced row doesn't exist, if I try to insert such a row using a new DB connection (while the first transaction hasn't been commited or rolled back yet) my 'insert into lock12_5 (lockid,lockinfo) values('bar','foo') appears to be blocked.
This behaviour seems to be MySQL specific, since with both Oracle 10g and MS SQL Server 2005 my 'insert' statement in the context of a separate DB connection wasn't blocked. Is this happening in MySQL due to the default isolation level being REPEATABLE_READ and MySQL gap locking? I'm using InnoDB engine. Quoting MySQL documentation:
"For locking reads (SELECT with FOR UPDATE or LOCK IN SHARE MODE), UPDATE, and DELETE statements, locking depends on whether the statement uses a unique index with a unique search condition, or a range-type search condition. For a unique index with a unique search condition, InnoDB locks only the index record found, not the gap before it. For other search conditions, InnoDB locks the index range scanned, using gap locks or next-key (gap plus index-record) locks to block insertions by other sessions into the gaps covered by the range."
It's not quite clear to me so far as to why MySQL creates a lock on a non-existent row... I thought my 'update' query falls into the 'unique index with a unique search condition' bucket, and since 0 records are found there would be no lock...
thanks in advance for any tips/hints/clarifications
Greg
p.s.
mysql> select version();
+------------+
| version() |
+------------+
| 5.5.12-log |
+------------+
I'm trying to understand why the following scenario behaves differently when dealing with MySQL to what I've seen when interacting with Oracle and MS SQL Server.
I have a table with two columns, 'show index' output is as follows:
Table, Non_unique, Key_name, Seq_in_index, Column_name, Collation, Cardinality, Sub_part, Packed, Null, Index_type, Comment, Index_comment
'lock12_5', '0', 'PRIMARY', '1', 'lockid', 'A', '11348', NULL, NULL, '', 'BTREE', '', ''
'lock12_5', '0', 'PRIMARY', '2', 'lockinfo', 'A', '11348', NULL, NULL, '', 'BTREE', '', ''
Using my first MySQL DB connection I'm executing (autocommit = 0) 'update lock12_5 set lockinfo='foo' where lockid='bar' and lockinfo='foo' and checking the return value. Whenever this query returns 0 and thus the referenced row doesn't exist, if I try to insert such a row using a new DB connection (while the first transaction hasn't been commited or rolled back yet) my 'insert into lock12_5 (lockid,lockinfo) values('bar','foo') appears to be blocked.
This behaviour seems to be MySQL specific, since with both Oracle 10g and MS SQL Server 2005 my 'insert' statement in the context of a separate DB connection wasn't blocked. Is this happening in MySQL due to the default isolation level being REPEATABLE_READ and MySQL gap locking? I'm using InnoDB engine. Quoting MySQL documentation:
"For locking reads (SELECT with FOR UPDATE or LOCK IN SHARE MODE), UPDATE, and DELETE statements, locking depends on whether the statement uses a unique index with a unique search condition, or a range-type search condition. For a unique index with a unique search condition, InnoDB locks only the index record found, not the gap before it. For other search conditions, InnoDB locks the index range scanned, using gap locks or next-key (gap plus index-record) locks to block insertions by other sessions into the gaps covered by the range."
It's not quite clear to me so far as to why MySQL creates a lock on a non-existent row... I thought my 'update' query falls into the 'unique index with a unique search condition' bucket, and since 0 records are found there would be no lock...
thanks in advance for any tips/hints/clarifications
Greg
p.s.
mysql> select version();
+------------+
| version() |
+------------+
| 5.5.12-log |
+------------+