MySQL使并发SELECT ... FOR UPDATE查询失败,而不是等待释放锁

时间:2014-07-16 21:20:37

标签: php mysql transactions innodb

在我的PHP代码中,如果另一个线程已在该行上执行事务,我将尝试使innoDB数据库事务被忽略。这里以一些代码为例:

$db = connect_db();
try{
    $db->beginTransaction();
    $query = "SELECT val FROM numbers WHERE id=1 FOR UPDATE"; //I want this to throw an exception if row is already selected for update
    make_query($db,$query); //function I use to make queries with PDO

    sleep(5); //Added to delay the transaction
    $num = rand(1,100);

    $query = "UPDATE numbers SET val='$num' WHERE id=1";
    make_query($db,$query);
    $db->commit();
    echo $num;
}
catch (PDOException $e){
    echo $e;
}

当它进行SELECT val FROM numbers WHERE id=1 FOR UPDATE查询时,如果线程正在等待另一个线程完成它的事务并释放锁,我需要通过php知道某种方式。最终发生的是第一个线程完成事务,第二个线程随后立即覆盖其更改。相反,我希望第一个事务完成,第二个事务要回滚或提交而不做任何更改。

1 个答案:

答案 0 :(得分:2)

考虑使用GET_LOCK()

模拟记录锁

选择特定于要锁定的行的名称。例如' numbers_1'

致电SELECT GET_LOCK('numbers_1',0)以锁定名称' numbers_1' ..如果名称可用,它将返回1并设置锁定;如果已设置锁定,则返回0。第二个参数是超时,0表示立即。返回0时,您可以退出。

完成后使用SELECT RELEASE_LOCK('numbers_1')

注意;在事务中再次调用GET_LOCK()将释放先前设置的锁。