PHP/MySQL 并发 - 写依赖于读 - 临界区

标签 php mysql multithreading concurrency critical-section

我有一个运行 PHP+MySQL 的网站。它是一个多用户系统,大多数 MySQL 表都是基于 MyISAM 的。

以下情况让我困惑了最近几个小时: 我有两个(并发)用户 A、B。他们两个都会这样做:

  1. 对表 1 执行读取操作
  2. 对另一个表 2 执行写入操作(仅当先前的读取操作将返回不同的结果时,例如 STATUS="OK")

B 对 A 有点延迟。

所以会这样发生:

  • 用户 A 读取表 1 并看到 STATUS="OK"。
  • (用户 A 将时间表写在表 2 上)
  • 用户 B 对表 1 进行了读取,但仍然看到 STATUS="OK"。
  • 用户 A 在表 2 上执行写入(导致 STATUS="NOT OK"了)
  • 用户 B 对表 2 执行写入(假设 STATUS="OK")

如果读取表 1 和写入表 2 被定义为临界区并自动执行,我认为我可以防止这种情况发生。我知道这在带有线程等的 Java 中工作得很好,但是据我所知,在 PHP 中没有线程通信。

所以我的问题的解决方案一定是与数据库相关的,对吧? 有什么想法吗?

非常感谢!

最佳答案

正确的方法:使用 InnoDB 和 transactions .

错误但有效的方法:使用 GET_LOCK() MySQL 函数在执行数据库操作之前获得一个独占命名锁。完成后,用 RELEASE_LOCK() 释放锁.由于只有一个客户端可以拥有一个特定的锁,这将确保“关键部分”中同时存在的脚本实例不会超过一个。

伪代码:

SELECT GET_LOCK('mylock', 10);
If the query returned "1":
    //Read from Table 1
    //Update Table 2
    SELECT RELEASE_LOCK('mylock');
Else:
    //Another instance has been holding the lock for > 10 seconds...

关于PHP/MySQL 并发 - 写依赖于读 - 临界区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12027096/

相关文章:

php - Laravel 选择菜单显示从数据库中选择的内容

php - 在php/mysql/apache环境中生成SEF页面

java - 使用带有多线程的camel框架进行组件测试

c# new thread from timer handle 问题

php - mysql数据库的html表单选项值只存储第一个字

mysql - 在不使用参数计划的情况下在 mysql 数据库中输入新数据时通知 Logstash

C# 转换错误 (DataRow)

python - Django 中数据库的下载链接

c# - 不明白 Monitor.Pulse() 的必要性

php - MySQL 检查数据库中的用户名和密码是否匹配