Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>It's not the same lock - the lock transaction 1 has is on the (index) record only and not the gap lock. </p> <p>Here's what's happening:</p> <ol> <li>Transaction 2 gets a lock for the (index) record <em>but not the gap before the record</em> ('rec but not gap'), i.e. it has a record lock only.</li> <li>Transaction 1 tries to get a lock on the record and the gap before (i.e. a next-key lock), but can't because transaction 2 has a record lock (and so transaction 1 waits). </li> <li>Transaction 2 tries to get a lock on the record <em>and the gap before</em> (i.e. a next-key lock) and can't because Transaction 1 is already waiting for the same lock and is ahead of it in the queue.</li> <li>Deadlock.</li> </ol> <p>I'm not entirely sure why Transaction 2 doesn't acquire a next-key lock immediately - perhaps the process of obtaining the record lock and then the gap lock isn't atomic (in the general sense of the word). </p> <p>I think the issue is that you have a composite primary key (id, value1) but you are deleting from a range (specifying id only) - this requires gap locks. See <a href="http://dev.mysql.com/doc/refman/5.0/en/innodb-record-level-locks.html" rel="noreferrer">http://dev.mysql.com/doc/refman/5.0/en/innodb-record-level-locks.html</a>, in particular:</p> <blockquote> <p>Gap locking is not needed for statements that lock rows using a unique index to search for a unique row. (This does not include the case that the search condition includes only some columns of a multiple-column unique index; in that case, gap locking does occur.)</p> </blockquote> <p>Can you change your code so you specify the full primary key when deleting, i.e. id <em>and</em> value1?</p> <p>Other options:</p> <ul> <li>Retry the delete when there's a deadlock, e.g. catch the error in your code and then retry if it was caused by a deadlock. This approach is often easier said than done, especially in legacy applications, but it is recommended by the MySQL page on <a href="http://dev.mysql.com/doc/refman/5.0/en/innodb-deadlocks.html" rel="noreferrer">how to cope with deadlocks</a>: </li> </ul> <blockquote> <p>Always be prepared to re-issue a transaction if it fails due to deadlock. Deadlocks are not dangerous. Just try again.</p> </blockquote> <ul> <li>Lock the whole table with a table-level lock before issuing the delete statement. This may affect performance though and is a 'sledgehammer' approach.</li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload