我使用的是MySQL 5.1,PHP 5.3,表格是MyISAM。这是这个假表的DTD:
CREATE TABLE `temp1` (
`value` varchar(10) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
此脚本基本上打印表temp1
的行计数,然后插入一行,然后再次打印行计数,然后休眠一秒钟并再次打印行计数。 INSERT由write
用户完成,SELECT由read
用户完成。
<?php
$value = "test";
$ro_user = "ro";
$ro_pass = "ro";
$write_user = "write";
$write_pass = "write";
$db_name = "db";
$ro_db = mysql_connect('localhost', $ro_user, $ro_pass);
mysql_select_db($db_name, $ro_db);
$res = mysql_query("SELECT * FROM temp1 WHERE value = '" . mysql_real_escape_string($value) . "'", $ro_db);
var_dump(mysql_num_rows($res));
$write_db = mysql_connect('localhost', $write_user, $write_pass);
mysql_select_db($db_name, $write_db);
mysql_query("INSERT INTO temp1 (`value`) VALUES ('" . mysql_real_escape_string($value) . "')", $write_db);
$res = mysql_query("SELECT * FROM temp1 WHERE value = '" . mysql_real_escape_string($value) . "'", $ro_db);
var_dump($res);
var_dump(mysql_num_rows($res));
sleep(1);
$res = mysql_query("SELECT * FROM temp1 WHERE value = '" . mysql_real_escape_string($value) . "'", $ro_db);
var_dump($res);
var_dump(mysql_num_rows($res));
打印输出通常是这样的:
int(12)
resource(8) of type (mysql result)
int(12)
resource(9) of type (mysql result)
int(13)
这似乎表明在执行第二个INSERT
查询时SELECT
尚未完全完成。所以我的问题是:
即使更奇怪,我无法在MySQL 5.5或5.6或任何InnoDB表中重现此行为。没有竞争条件出现在那里。