PHP / MySQL同步innoDB查询作为异步工作

时间:2015-12-08 00:39:12

标签: php mysql innodb

我需要使用不同的PHP脚本同时更新和读取一个表中的数据。 我创建printf( "|%-20s|%-10.1f|%-10.1f|%-10.1f|%-10.1f|\n", ...作为脚本会话标识符(同时处理大约20个脚本),并在表行中设置100行的会话标识符。之后,它将按会话标识符选择为此脚本保留的行。在while循环中,脚本将对数据执行一些操作并更新保留的行。

但是脚本不能同时工作,第一个脚本运行正常,但是其他脚本在第一个脚本运行时没有先进行查询。我在我的数据库管理应用程序中看到它。

$sess

创建表格语法

$sess = intval(str_replace(".", "", microtime(TRUE)));
sql_query("UPDATE locations SET sess='$sess' WHERE sess='0' LIMIT 100");
$r = sql_query("SELECT * FROM locations WHERE sess='$sess'");
while ($q = sql_row($r))
{

1 个答案:

答案 0 :(得分:0)

您是否在交易中(BEGIN ... COMMIT)?如果是这样,你已经锁定了那100行。同上autocommit=0

相反,请确保UPDATE(用于将“队列”中的100个项目分配给您的流程)本身就是一个交易。

然后,假设其他线程无法以相同的微秒(一个可疑的假设)调用microtime,则会安全地为您分配100个项目。然后你可以开始另一个交易(如果需要)并处理它们。

然而,100行SELECT将不必要地对这些行进行读锁定。

因此...

START TRANSACTION;
UPDATE ... LIMIT 100;
SELECT ...
COMMIT;

foreach ...
    START TRANSACTION;
    work on one item
    COMMIT;
end-for

目前还不清楚第二个START-COMMIT是否应该在for循环内或外部。内部会变慢,但可能会更正,这取决于"工作"你在做什么,需要多长时间。 (你不想ROLLBACK 99成功'工作'因为第100个花了太长时间。)

你以后在做DELETE ... WHERE sess = $sess吗?如果你像那样大量删除,那么在for循环之后在单独的事务中执行它。

目标:将排队交易与应用程序交易隔离开来。

请注意,隔离将更容易编码错误/死锁/等。 (你 检查,对吗?)