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

标签 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某种方式了解线程是否正在等待另一个线程完成其事务并释放锁。最终发生的情况是第一个线程完成事务,第二个线程随后立即覆盖其更改。相反,我希望第一个事务完成,第二个事务回滚或提交而不进行任何更改。

最佳答案

考虑使用 GET_LOCK() 模拟记录锁

选择一个特定于您想要锁定的行的名称。例如“numbers_1”。

调用SELECT GET_LOCK('numbers_1',0)来锁定名称'numbers_1'。如果名称可用,它将返回1并设置锁定,如果锁定可用,则返回0已经设置了。第二个参数是超时时间,0表示立即执行。返回 0 时您可以退出。

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

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

关于php - MySQL 使并发 SELECT ... FOR UPDATE 查询失败而不是等待锁被释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24790968/

相关文章:

php - 拉拉维尔 :login using custom middleware

php - 在 PHP 中去除新行

java - Spring MVC Hibernate 应用程序加载数据库表

reactjs - 如何追踪MultiversX网络上的交易状态?

java - 使用 Spring 以事务方式安全地从一个 EAR 文件调用另一个 EAR 文件的 "correct"方法是什么?

c# - Nhibernate session.BeginTransaction() 与 transaction.Begin()

php - php 和 mysql 页面中的性能问题

php - session cookies = cookies?

mysql - rails : Find all children from the same generation

mysql - 在mysql中从扑克牌中找到两对