【问题标题】:PHP + MySQL/MariaDB + avoid race condition [duplicate]PHP + MySQL/MariaDB + 避免竞争条件 [重复]
【发布时间】:2019-05-03 15:53:30
【问题描述】:

我使用 Apache、MySQL 和 PHP 开发了一个 Web 应用程序。

此网络应用程序允许多个用户登录应用程序。 然后,通过应用程序,他们可以访问数据库。

由于当两个或更多用户尝试 SELECT/UPDATE/DELETE 相同的信息(在我的例子中是表格的一行)时可能会出现竞争条件,所以我正在寻找避免这种竞争条件的最佳方法。

我尝试使用 mysqli 并将 autocommit 设置为 OFF 并使用 SELECT .... FOR UPDATE,但这无法像我理解的那样使用 PHP,每个事务都会自动提交,并且每个与 db 的连接都在为用户提供/加载 PHP -->html 页面时自动释放。

阅读了一些帖子后,我的问题似乎有两种可能的解决方案:

  1. 使用 PDO。据我了解,PDO 创建与数据库的连接,这些连接在 html 页面加载时不会释放。但应采取特殊预防措施,因为锁可能会保留,例如用户退出页面,PDO连接还未释放...

  2. 在对应表中添加“锁定”列以标记锁定行。所以例如仅当相应用户已锁定行进行编辑时,才可能执行 UPDATE 事务。其他用户不得修改。

我在使用 PDO 时可能遇到的主要问题是我必须修改 PHP 代码才能在适用的情况下用 PDO 替换 mysqli。

场景 2 的问题是我还需要修改我的数据库架构,为锁定/解锁添加额外的编码,并考虑“挂起”锁定行的可能性,这可能会导致在表中添加额外的列(例如,存储行被锁定的时间和lockedBy信息)和代码(例如,在用户端运行Javascript,它将更新锁定时间,以便用户在使用时不断标记行......)

非常感谢您根据您的经验提供的 cmet !!!

谢谢。

【问题讨论】:

  • 您应该决定的第一件事是您想要悲观并发还是乐观并发。例如,假设两个用户试图在给定时间修改记录。用户 A 打开记录,用户 B 打开记录,其中一个保存,然后另一个保存。这种情况应该如何在您的用户体验中发挥作用?当第二个用户尝试打开时,他们是否应该收到一条消息说其他人打开了它?当第二个用户尝试保存时,他们是否应该收到其他人保存并需要刷新的消息?还有什么?
  • 如果用户同时编辑数据库中的同一个单元格,你希望是什么?然后你会向其他用户展示什么?
  • @David 同样的想法:D

标签: php mysql pdo race-condition autocommit


【解决方案1】:

这可能是一个意见而不是技术答案,但写成评论太长了。

我想把它想象成在电影或航班中预订座位:当用户选择座位并按下下一步时,该座位将为该用户保留一段时间,而当用户没有在给定的时间内完成,它会得到一个超时异常,而无需进一步处理。您可以在行之外使用编辑按钮,当用户单击它时,在服务器端检查该行是否保留给其他人,如果没有,则将其保留给用户。当其他用户在该用户之后也单击编辑按钮时,他们将不会获得编辑表单。我不知道数据库系统如何处理这个问题。

但是,确保它的一种方法是在用户编辑后重新读取该行并将其提交以显示用户。如果任何锁定机制阻止了行的更新,用户也将通过看不到行中的更改来知道它。

【讨论】:

  • 您好,感谢您的反馈。在我的情况下,第二个(或第三个或......)用户应该无法访问该记录进行编辑。因此,他们会收到一条消息,指出该记录当前已被用户 1 锁定(例如,通过 JavaScript 弹出窗口)。但是必须以某种方式保护该行,以便如果例如用户 1 关闭他编辑该行的选项卡/窗口,该行应该被解锁。如果他的浏览器也一样,例如崩溃或挂起...
  • 在启用行编辑器之前,您需要使用 ajax 检查并锁定。
猜你喜欢
  • 1970-01-01
  • 2015-01-30
  • 2010-09-25
  • 1970-01-01
  • 1970-01-01
  • 2021-03-12
  • 1970-01-01
  • 2010-09-25
  • 2019-06-12
相关资源
最近更新 更多