получить значение автоинкремента для вставленной строки безопасно - PullRequest
2 голосов
/ 16 сентября 2011

у меня есть таблица в базе данных, которая содержит _id столбец, который является первичным ключом для этой таблицы, фактически значение этого столбца задается методом автоматического увеличения, есть ли безопасный способ получить значение, которое автоматически увеличивает значениедал строку я, когда я делаю вставку ???я видел решение говорит: "позвоните mysql_insert_id() сразу после вашего запроса вставки."это безопасно использовать (то есть он получает неправильное значение, если один и тот же сценарий в другом потоке) ???если нет, то есть ли способ сделать синхронизированный блок в php?

Ответы [ 5 ]

3 голосов
/ 16 сентября 2011

Насколько я знаю, идентификатор, возвращаемый из mysql_insert_id, является идентификатором автоматического приращения из последнего запроса на вставку для текущего подключения (mysql_connect) к базе данных sql.Единственная причина, по которой он вызывается сразу после запроса, состоит в том, что если вы запускаете два запроса вставки сразу после друг друга, mysql_insert_id возвращает только последний запрос.Не было бы надежно получить идентификатор из первого запроса.Кроме того, он получает идентификатор из последнего запроса, поэтому, если вы выполнили вставку, а затем обновили, запустили mysql_insert_id.Он вернет 0, потому что последний запрос (обновление) не является вставкой.

Кроме того, php просто вызывает функцию mysql mysql_insert_id .Из руководства mysql:

На значение mysql_insert_id () влияют только операторы, выпущенные в текущем клиентском соединении.На него не влияют заявления других клиентов.

1 голос
/ 16 сентября 2011

Да; $ id = mysql_insert_id (); сразу после вашего запроса.

0 голосов
/ 31 марта 2018

В 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;
?>
0 голосов
/ 16 сентября 2011

Обычно это безопасно, но могут быть проблемы с синхронизацией.

Я предлагаю поместить ваши sqls в блок транзакций:

mysql_query('BEGIN TRANSACTION');

mysql_query('INSERT...');

$x = mysql_insert_id();

mysql_querry('COMMIT');

РЕДАКТИРОВАТЬ: вы также можете установить блокировку записи на таблицу, пока вы не прочитаете идентификатор, а затем снимите блокировку. Но это нужно только в том случае, если у вас проблемы с синхронизацией (тот же поток)

0 голосов
/ 16 сентября 2011

Если каждый из ваших потоков использует свое собственное соединение с сервером MySQL, все должно быть в порядке.Если нет, вам, вероятно, придется использовать мьютекс или семафор, которые должны предоставляться вашей библиотекой потоков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...