Example of select lock in share mode taken from MySQL documentation:

As an example of a situation in which a locking read is useful, suppose that you want to insert a new row into a table child, and make sure that the child row has a parent row in table parent. Suppose that you use a consistent read to read the table parent and indeed see the parent row of the to-be-inserted child row in the table. Can you safely insert the child row to table child? No, because it is possible for some other session to delete the parent row from the table parent in the meantime without you being aware of it.

The solution is to perform the SELECT in a locking mode using LOCK IN SHARE MODE:

<?php

  DB::query("start transaction");

  $q = DB::query("SELECT parentID FROM parent WHERE NAME = 'Jones'
                         LOCK IN SHARE MODE;");

  if( count($q) === 1)
    DB::query("insert into child set parentName = 'Jones', ... other data");

  DB::query("commit;");
?>

SELECT ... LOCK IN SHARE MODE sets a shared mode lock on any rows that are read. Other sessions can read the rows, but cannot modify them until your transaction commits.

What happens if code execution fails (php bugs, operating system bugs, power failure, ...) just after we executed query start transaction; select parentID from parent where name = 'Jones' lock in share mode;. How long does row stays locked for updating and deleting ? I want to make sure that even if execution fails that row will not stay locked (let us say that PHP failed but MySQL is still running). How does MySQL handles this situation. I suppose in worst case timeout occurs like this:

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

and MySQL unlocks locked rows. Or is there any better mechanism.

有帮助吗?

解决方案

In case the error causes the connection to get closed - MySql rollbacks the whole transaction, and all locks are released.
In case the connection is not closed (power failure, the application hangs etc.) - MySql will close the connection after time perior defined by wait_timeout or interactive_timeout variables. Closing the connection causes a rollback of the active transaction, and all locks are released.

wait_timeout --> http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_wait_timeout
interactive_timeout --> http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_interactive_timeout

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top