安全地获取插入行的自动增量值

时间:2011-09-16 16:01:35

标签: php mysql synchronization

我在数据库中有一个表包含_id列,这是该表的主键,实际上这个列值是由自动增量方法设置的,有没有任何安全的方法来获取auto的值当我插入时给予行i的增量值???我看到一个解决方案说:“在插入查询后立即调用mysql_insert_id()。”是否可以安全使用(即如果在不同的线程中相同的脚本,它会得到一个错误的值)???如果没有,有没有办法在PHP中制作同步块?

6 个答案:

答案 0 :(得分:3)

据我所知,从mysql_insert_id返回的id是从当前连接(mysql_connect)的最后一次插入查询到sql数据库的自动增量id。在查询之后必须立即调用它的唯一原因是,如果你在彼此之后运行两个插入查询,mysql_insert_id只返回最后一个查询。从第一个查询中获取id是不可靠的。此外,它从最后一个查询中获取id,因此如果您执行了插入然后更新,则运行mysql_insert_id。它将返回0,因为最后一个查询(更新)不是插入。

另外,php只调用mysql函数mysql_insert_id。从mysql手册:

  

mysql_insert_id()的值仅受发出的语句的影响   在当前客户端连接中。它不受陈述的影响   由其他客户发布。

答案 1 :(得分:1)

是; $ id = mysql_insert_id();在您的查询后直接。

答案 2 :(得分:0)

如果你的不同线程都使用自己的连接到MySQL服务器,它应该没问题。如果没有,您可能必须使用互斥锁或信号量,这应该由您的线程库提供。

答案 3 :(得分:0)

这样做通常很安全,但可能存在同步问题。

我建议将您的sqls放入交易区:

mysql_query('BEGIN TRANSACTION');

mysql_query('INSERT...');

$x = mysql_insert_id();

mysql_querry('COMMIT');

编辑:你也可以在表上放一个写锁,直到你读到id然后释放锁。但是如果你有同步问题(同一个线程),你只需要这个

答案 4 :(得分:0)

在PDO中,正确的方法是使用PDO::lastInsertId()

<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";

try{
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    // set the PDO error mode to exception
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $sql = "INSERT INTO MyGuests (firstname, lastname, email)
    VALUES ('John', 'Doe', 'john@example.com')";
    // use exec() because no results are returned
    $conn->exec($sql);
    $last_id = $conn->lastInsertId();
    echo "New record created successfully. Last inserted ID is: " . $last_id;
}catch(PDOException $e){
    echo $sql . "<br>" . $e->getMessage();
}

$conn = null;
?>

答案 5 :(得分:0)

同样,您可以使用一个查询来获取自动增量ID,例如:

INSERT INTO table_name(field_1,field_2) VALUES(:field_1,:field_2) RETURNING id;

INSERT INTO table_name (field_1) OUTPUT INSERTED.id VALUES (?);

两个都返回您的自动增量ID 关于: https://www.php.net/manual/en/pdo.lastinsertid.php