PHP + MySQL / MariaDB +避免出现竞争情况

时间:2018-12-01 21:52:40

标签: php mysql pdo race-condition autocommit

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

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

由于当两个或多个用户尝试选择/更新/删除相同信息(在我的情况下是表的一行)时可能会出现竞争条件,所以我正在寻找避免此类竞争条件的最佳方法。

我尝试使用mysqli并将autocommit设置为OFF并使用SELECT .... FOR UPDATE,但这无法工作-就我所知-使用PHP,每个事务都会自动提交,并且每个与数据库的连接都在为用户提供/加载PHP-> html页面时自动释放。

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

  1. 使用PDO。据我了解,PDO会创建与数据库的连接,而在html页面加载时这些连接不会释放。尽管应采取特殊的预防措施,但如果例如用户退出页面且PDO连接尚未释放...

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

PDO可能存在的主要问题是,我必须修改PHP代码,以便在适用的情况下用PDO替换mysqli。

方案2的问题是,我还需要修改数据库架构,添加用于锁定/解锁的其他编码,还要考虑“挂起”锁定行的可能性,这可能导致在表中添加其他列(例如,存储行被锁定的时间和lockedBy信息)和代码(例如,在用户端运行将更新锁定时间的Javascript,以便用户在使用时连续标记该行...)

根据您的经验发表的评论将不胜感激!

谢谢。

1 个答案:

答案 0 :(得分:0)

这可能是一种意见,而不是技术性的答案,但是将其写成评论太久了。

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

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