当尝试在PHP中插入行后立即选择行时,我会间歇性地看到一个问题。这个问题只会在每100到1000次发生一次.这是使用php4.4,没有任何升级/能够使用PDO或mysqli的选项。我正在考虑使用事务,但这两个查询都执行并且将继续执行,即使使用事务,但第二个查询运行并返回空的RS,因此我怀疑事务是否会孵化它。
例如,一个有两列的表:一个自动增量计数器和一个存储值。值也必须是唯一的,但是联接是在计数器上进行的,而不是在值上进行的。值可以由多个用户一次输入,所以我不能简单地信任最高的计数器给我刚才插入的值。
data:
data_id int(11) UNIQUE AUTO_INCREMENT NOT NULL
myData varchar(50) UNIQUE NOT NULL现在每个用户都可以在任何时候输入一个新的$val,当他们输入它时,还必须在status表中输入一个条目。
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将执行并不返回任何行。数据插入将正确执行。我不认为这是可能的,因为insert或die迫使PHP等待返回值,以便它知道是否执行行的“或死”部分。PHP是否可能在执行完insert命令之前收到了insert命令的返回值,因此insert后面的select语句无法返回任何行?将来如何才能防止这种间歇性问题呢?
发布于 2013-09-06 16:15:31
您试图插入的数据(当您没有得到预期的错误消息)是否是一个重复的记录(即与表数据中已经存在的记录相匹配)?
如果是,请参见
具体而言,引用mysqlgatchas的话:
"...A的另一个特点似乎就是这种行为:
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)预期的行为是该语句失败时会出现与上面相同的错误;相反,该语句似乎成功了,只有重复的:1表明该语句实际上被忽略的通知。
Update:在版本4.0.20中,以及以前的版本中,此语句返回预期的错误消息.“
发布于 2013-09-06 16:38:39
虽然如果您的表是MyISAM,那么我怀疑您的物理表结构中有一些草图,但没有一个很好的解释来解释为什么有时会失败。否则,您的未转义字符串中的值可能会导致查询无法找到它刚刚插入的内容。
您插入的最后一行的正确标识方法如下:
SELECT LAST_INSERT_ID();或者这个:
SELECT @@LAST_INSERT_ID;它们是等价的,并且总是会给您分配给您插入的最后一行的自动增量列的值--即使另一个会话在您之后插入了数据。
https://stackoverflow.com/questions/18661643
复制相似问题