Php 从两个或多个脚本访问/更新一个表的最佳方法?
背景 我有一个包含两个或多个PHP脚本将同时访问的数据的表。数据如下所示:Php 从两个或多个脚本访问/更新一个表的最佳方法?,php,mysql,Php,Mysql,背景 我有一个包含两个或多个PHP脚本将同时访问的数据的表。数据如下所示: +--------+-------------------+-----------+-----------+ | ID | Start | End | Status | +--------+-------------------+-----------+-----------+ | 1 | 1000 | 1500 | 0
+--------+-------------------+-----------+-----------+
| ID | Start | End | Status |
+--------+-------------------+-----------+-----------+
| 1 | 1000 | 1500 | 0 |
| 2 | 1000 | 1500 | 0 |
| 3 | 1000 | 1500 | 0 |
| 4 | 1000 | 1500 | 0 |
+--------+-------------------+-----------+-----------+
PHP脚本在启动时执行以下查询:
SELECT * FROM `table` WHERE `Status` = 0 LIMIT 1
然后,PHP脚本执行从开始
值到结束
值(1000到1500)的循环。完成后,它将该行的状态更新为'1'
。它会自动重定向到自身并重新启动整个过程
我面临的挑战是:
如果我希望两个或多个相同的PHP脚本同时运行以访问相同的数据库,那么如何确保它们不是访问相同的记录
更大的挑战是,如果我想在同一个PHP脚本的多个实例上拆分从start
到end
的循环,即每100个值是脚本的一个实例,并且在达到1100
之后,将MySQLStart
更新为1100
,并重定向到从1101
开始的同一脚本到1200
,依此类推,直到达到End
编号。达到结束
编号后,该记录的状态
将设置为1
,并移动到下一条记录。在实际情况中,它从开始到结束大约有一百万个计数,一些内存密集型函数在循环中执行,所以我需要将其分块
关于行级锁定的所有知识,我都是在最后几分钟学到的;所有这些似乎都无法解决来自一个脚本的多实例锁定问题
我应该考虑会话ID/Cookie吗?你推荐什么?
我建议:
使用支持行级锁定的InnoDB
:
ALTER TABLE`TABLE`ENGINE=InnoDB;
Status
值指示“正在进行”;为了更明确一点,让我们使用MySQL的ENUM
类型:
altertable`TABLE`
在状态后添加状态\新枚举('queued'、'inprogress'、'complete');
更新`table`SET status\u new=案例状态
当0然后“排队”时
当1“完成”时
结束;
改变TABLE`TABLE`的删除状态;
$dbh->setAttribute(PDO::ATTR_AUTOCOMMIT,FALSE);//pdo
$mysqli->autocommit(FALSE);//mysqli(OOP)
mysqli_自动提交($link,FALSE);//mysqli(程序性)
mysql_查询(“启动事务”);//ext/mysql*
从'table'中选择*,其中status_new='queued'LIMIT 1用于更新;
状态设置为“进行中”
:
UPDATE`table`SET status\u new='in progress',其中ID=?
$dbh->commit();//pdo
$mysqli->commit();//mysqli(OOP)
mysqli_提交($link);//mysqli(程序性)
mysql_查询('COMMIT');//ext/mysql*
再次更新
记录以将其标记为该记录ext/mysql
未被推荐在新代码中使用,现在在PHP v5.5中已被弃用。我建议:
ALTER TABLE`TABLE`ENGINE=InnoDB;
Status
值指示“正在进行”;为了更明确一点,让我们使用MySQL的ENUM
类型:
altertable`TABLE`
在状态后添加状态\新枚举('queued'、'inprogress'、'complete');
更新`table`SET status\u new=案例状态
当0然后“排队”时
当1“完成”时
结束;
改变TABLE`TABLE`的删除状态;
$dbh->setAttribute(PDO::ATTR_AUTOCOMMIT,FALSE);//pdo
$mysqli->autocommit(FALSE);//mysqli(OOP)
mysqli_自动提交($link,FALSE);//mysqli(程序性)
mysql_查询(“启动事务”);//ext/mysql*
从'table'中选择*,其中status_new='queued'LIMIT 1用于更新;
状态设置为“进行中”
:
UPDATE`table`SET status\u new='in progress',其中ID=?
$dbh->commit();//pdo
$mysqli->commit();//mysqli(OOP)
mysqli_提交($link);//mysqli(程序性)
mysql_查询('COMMIT');//ext/mysql*
再次更新
记录以将其标记为该记录*请注意,
ext/mysql
自2011年6月以来就不推荐在新代码中使用,现在在PHPV5.5中已被弃用。感谢您提供详细的答案。非常实用!这解决了第一个难题,我们可以锁定一行并将其标记为正在进行。但是对于第二个挑战,当脚本再次加载以处理记录中的下一个块时,我是否传递一个带有当前ID的GET查询字符串?或者我可以把“锁”带到下一个实例吗?@Reddox:这取决于你的安全要求。只要错误的GET
字符串(无论是恶意的还是acc)没有风险(或没有伤害),您的建议就可以了