在插入PHP后立即尝试选择一行时,我间歇性地发现问题。这个问题只会在每100-1000次发生一次。这是使用PHP 4.4,没有选项升级/能够使用PDO或mysqli。我正在考虑使用事务,但是两个查询都会执行,并且即使使用事务也会继续这样做,但是第二个查询会运行并返回空RS,所以我怀疑事务是否会影响它。
例如,选择一个包含两列的表:自动增量计数器和存储值。该值也必须是唯一的,但是在计数器上进行连接,而不是值。一次可以由多个用户输入值,所以我不能简单地相信最高的计数器给我刚刚插入的值。
data:
data_id int(11) UNIQUE AUTO_INCREMENT NOT NULL
myData varchar(50) UNIQUE NOT NULL
现在每个用户都可以随时输入新的$ val,当他们输入时,还必须在状态表中输入一个条目。
statuses:
status_id int(11) UNIQUE AUTO_INCREMENT NOT NULL
data_id int(11) NOT NULL
status int(1) NOT NULL
我用来完成此任务的代码是:
// Get value
$insData = $_GET['VAL'];
// Insert value
$ins = mysql_query( "INSERT INTO data (myData) VALUES ('" . $insData . "')" )
or die(mysql_error());
// Get value's id
$res = mysql_query( "SELECT data_id FROM data WHERE myData='" . $insData . "'" )
or die(mysql_error());
// From here I would insert into the statuses table,
// but the new entry into the data table is sometimes not found!
每运行100-1000次代码,select将执行并且不返回任何行。数据插入将正确执行。我不相信这是可能的,因为插入或死亡迫使PHP等待返回值,以便它知道是否执行该行的'或die'部分。是否有可能PHP在执行完毕之前从insert命令收到了返回值,因此紧跟在insert之后的select语句无法返回任何行?那将来如何防止这种间歇性问题?
答案 0 :(得分:0)
您尝试插入的数据(当您没有收到预期的错误消息时)是否存在重复记录(即匹配已存在于TABLE DATA中的记录)?
如果是,请参阅
具体来说,引自mysqlgatchas:
" ...进一步的特质似乎是这种行为:
CREATE TABLE insert_test2 (
id INT NOT NULL PRIMARY KEY,
txt VARCHAR(32)
);
INSERT INTO insert_test2 VALUES(1, 'foo');
INSERT INTO insert_test2 VALUES(2, 'bar');
现在看一下:
mysql> INSERT INTO insert_test2 VALUES(1, 'bar');
ERROR 1062: Duplicate entry '1' for key 1
正确行为......现在看一下:
mysql> INSERT INTO insert_test2 (id, txt) SELECT i.id, i.txt FROM insert_test i
WHERE i.id=1;
Query OK, 0 rows affected (0.00 sec)
Records: 1 Duplicates: 1 Warnings: 0
mysql> SELECT * FROM insert_test2;
+----+------+
| id | txt |
+----+------+
| 1 | foo |
| 2 | bar |
+----+------+
2 rows in set (0.00 sec)
此语句的预期行为将失败并出现与上述相同的错误;相反,它似乎是成功的,只有Duplicates:1通知表明该语句被有效忽略。
更新:在版本4.0.20以及可能的先前版本中,此语句返回预期的错误消息..."
答案 1 :(得分:0)
对于为什么偶尔失败,没有一个很好的解释,尽管如果你的桌子是MyISAM
,那么我怀疑你有一些粗略的爬行到你的物理桌面结构。否则,您的非转义字符串中的值可能会导致查询无法找到刚刚插入的内容。
确定你插入的最后一行的正确方法:
SELECT LAST_INSERT_ID();
或者这个:
SELECT @@LAST_INSERT_ID;
这些是等效的,并且总是会为您提供分配给>> 插入的最后一行的自动增量列的值 - 即使另一个会话已经在您之后插入了数据。