我的查询是否将行锁定以备下次使用

时间:2019-04-04 16:58:17

标签: php mysql database

这是我在php中的代码结构:

function myfunction(){

    try{    
        // begin Transaction

        // get last row by this query:
        // SELECT id FROM tableName WHERE t_date+INTERVAL 1 MINUTE< NOW() LIMIT 1
        // store the returned id inside $id if exists, $id=0 otherwise (out of id for now)

        // update the row to the current time to show it is fetched now by this query:
        // UPDATE tableNAME SET t_date=NOW() WHERE id=$id

        // end of Transaction
        // commit   

    }catch (PDOException $e){
        // failed, rollback
        $id = 0;
    }

    return $id
}

如您所见,我的功能:

  1. 用于锁定行的事务。
  2. 返回最近1分钟未返回的唯一行ID。
  3. 请求的用户拥有该ID 1分钟。
  4. 其他用户可以在1分钟后拥有该ID。

代码可以正常工作,我也没有任何与代码结构有关的问题。

问题

您可以看到,每个请求的ID始终应该是唯一的。我正在使用MySQL,想知道:

如果两个(或多个)用户同时打开页面,原因是:

  • 它们具有不同的PDO连接,并且
  • MySQL可以在不同的线程中同时运行两个或多个请求,并且
  • 因为我隔离了事务内部的提取查询,

我总是会得到预期的独特结果吗?

我已经阅读了关于Does MySQL queue queries?的@symcbean答案,他提到:

  

两个查询可以同时到达非常不可能-   但并非不可能

我的代码结构是否可以帮助我避免并行查询?

1 个答案:

答案 0 :(得分:2)

考虑到两个查询同时到达的情况,所有事务都保证了每个线程的数据库操作的ACID行为。这并不意味着两组选择/更新不能同时发生。这实际上可能会发生。

一种解决方法是使用SELECT ... FOR UPDATE

SELECT id FROM tableName WHERE t_date + INTERVAL 1 MINUTE < NOW() LIMIT 1 FOR UPDATE; UPDATE tableNAME SET t_date=NOW() WHERE id = $id; 子句将告诉MySQL锁定单个匹配的FOR UPDATE行,这样,即使有另一个线程进入,它也将无法锁定,因此无法更新。 / p>

编辑:

@tadman指出,您甚至可以在这里使用单个查询:

id