1

在数据库连接类上使用单例模式时,我想知道一件事。

据我了解,单例模式阻止创建使用该模式的给定类的超过 1 个对象。

假设我需要我刚刚插入的行中的 id,我通过mysqli::$insert_id. 如果连接对象的另一种用法同时用于插入一行,这可能会导致返回与预期不同的 id 的机会,还是肯定总是返回正确的 id?

对于新手问题,我很抱歉,我只是想知道在多用户应用程序上是否有很小的机会以这种方式获取 id 可能不一致。

提前致谢。

4

1 回答 1

3

从 MySQL 开始:

http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

生成的 ID 在每个连接的基础上维护在服务器中。这意味着函数返回给给定客户端的值是为影响该客户端的 AUTO_INCREMENT 列的最新语句生成的第一个 AUTO_INCREMENT 值。此值不受其他客户端的影响,即使它们生成自己的 AUTO_INCREMENT 值。这种行为确保每个客户端都可以检索自己的 ID,而不用担心其他客户端的活动,也不需要锁或事务。


让我们进行一些测试:

<?php
header('Content-Type: text/plain');

$con1 = new mysqli('localhost', 'root', '1', 'new_schema');
$con2 = new mysqli('localhost', 'root', '1', 'new_schema');

$sql = 'DROP TABLE IF EXISTS `x`';

$con1->query($sql);

$sql = <<<SQL
CREATE TABLE `x`(
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `value` VARCHAR(20)
)ENGINE=InnoDB;
SQL;

$con1->query($sql);

$sql = <<<SQL
INSERT INTO `x` (`id`, `value`)
VALUES (NULL, NULL);
SQL;

$con1->query($sql);
$con2->query($sql);

echo 'con1 == con2 is ',  $con1 == $con2  ? 'true' : 'false', PHP_EOL;
echo 'con1 === con2 is ', $con1 === $con2 ? 'true' : 'false', PHP_EOL;

echo '1: ', $con1->insert_id, PHP_EOL;
echo '2: ', $con2->insert_id, PHP_EOL;

$con1->close();
$con2->close();
?>

显示:

con1 == con2 is true
con1 === con2 is false
1: 1
2: 2

测试对象: PHP 5.4.5, MySQL 5.6.10.

于 2013-04-22T10:13:10.267 回答