Php mysql-行锁定和释放

Php mysql-行锁定和释放,php,mysql,sql,Php,Mysql,Sql,我有两个表'reservation'和'spot'。在预订过程中,会检查spot表中的'spotStatus'列,如果有空,则会对其进行更新。一个用户只能保留一个位置,为了确保没有其他用户可以保留相同的位置,我该怎么办 参考这里的一些答案,我发现行锁定和表锁定是解决方案。我应该像这样执行查询吗 "select * from spot where spotId = id for update;" 然后对状态执行必要的更新,或者有其他优雅的方法来完成吗 我关心的是如果 1. Transactio

我有两个表'reservation'和'spot'。在预订过程中,会检查spot表中的'spotStatus'列,如果有空,则会对其进行更新。一个用户只能保留一个位置,为了确保没有其他用户可以保留相同的位置,我该怎么办

参考这里的一些答案,我发现行锁定和表锁定是解决方案。我应该像这样执行查询吗

"select * from spot where spotId = id for update;" 
然后对状态执行必要的更新,或者有其他优雅的方法来完成吗

我关心的是如果

1. Transaction doesnot complete successfully?  
2. what happens if both user tries to reserve the same row at the same time? are both transactions cancelled? 
锁什么时候释放

  • 如果未成功,数据库将返回到事务(回滚)之前的数据,就像从未发生过一样
  • 和它不在同一时间一样。其中只有一个会锁定数据库,另一个不会被创建

  • 这里的问题是在竞态条件下,即使事务在默认情况下如果使用得很简单也不会阻止-即使两个保留同时发生,例如来自运行PHP的两个不同Apache进程,事务锁定只会确保保留被正确序列化,因此,第二个仍将覆盖第一个

    通常情况下,这种情况并不重要,考虑到数据库和服务器作为一个整体的速度,与平均预订站点上的负载相比,这种情况导致问题的可能性小于连续两次赢得州彩票。然而,如果你正在实施一个网站,该网站将在30秒内售出5万张酷玩音乐会门票,那么机会将急剧上升


    一个简单的解决方案是实现一种“保留意图”,不直接覆盖现场保留,而是将保留意图附加到一个单独的时间戳表中。插入后,您可以清除此表中的重复项,优先选择最旧的,并将其应用于实时数据。

    如果您使用teradata,则可以使用队列表概念。

    mysql中有自动行锁定,您不必这样做。您需要的是一个具有正确设置的外键的唯一索引或主索引,以便您的实体关系与它们应该匹配的关系,如多对一等,。。如果您关心事务的失败,则存在
    commit
    rollback
    如果
    commit
    失败。理论上,竞争条件总是可能的,因为每个事务都是独立运行的。因此,如果两个用户同时尝试预订,他们可能都会得到他们的位置。实际上,发生这种情况的可能性取决于您可能有多少并发更新。