Как начать и завершить транзакцию в mysqli?
Насколько я понял, транзакция начинается, когда мы вызываем $mysqli->autocommit(FALSE);
и заканчивается после вызова $mysqli->commit();
как в приведенном ниже примере.
<?php
//Start transaction
$mysqli->autocommit(FALSE);
$mysqli->query('UPDATE 'table' SET 'col'=2');
$mysqli->query('UPDATE 'table1' SET 'col1'=3;');
$mysqli->commit();
//End transaction
//Executing other queries without transaction control
$mysqli->query("Select * from table1");
$mysqli->query("Update table1 set col1=2");
//End of executing other queries without transaction control
//Start transaction
$mysqli->autocommit(FALSE);
$mysqli->query('UPDATE 'table' SET 'col'=2');
$mysqli->query('UPDATE 'table1' SET 'col1'=3;');
$mysqli->commit();
//End transaction
?>
Правильно ли я понял? Если бы вы не исправили меня, потому что на самом деле я впервые использовал транзакции в реальной жизни.
Спасибо.
Ответы
Ответ 1
Ну, согласно документу php, вы правы.
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$mysqli->query("CREATE TABLE Language LIKE CountryLanguage");
/* set autocommit to off */
$mysqli->autocommit(FALSE);
/* Insert some values */
$mysqli->query("INSERT INTO Language VALUES ('DEU', 'Bavarian', 'F', 11.2)");
$mysqli->query("INSERT INTO Language VALUES ('DEU', 'Swabian', 'F', 9.4)");
/* commit transaction */
$mysqli->commit();
/* drop table */
$mysqli->query("DROP TABLE Language");
/* close connection */
$mysqli->close();
?>
В приведенном выше примере:
-
CREATE TABLE
автоматически фиксируется, потому что это поведение по умолчанию. -
INSERT INTO
не INSERT INTO
автоматически из-за автоматической autocommit(FALSE)
. -
DROP TABLE
автоматически фиксируется, потому что autocommit(FALSE)
был сброшен с помощью ->commit();
,
Ответ 2
j0k в основном верно, кроме как в выпадающей таблице.
Автоматическое принятие не включено с помощью → commit()
Вместо этого DROP TABLE является запросом DDL, а запросы DDL всегда неявно фиксируются и будут фиксировать всю вашу ранее не зафиксированную работу.
Таким образом, если вы не зафиксировали работу, запрос DDL приведет к принудительной фиксации.
Ответ 3
Подготовьте оператор SQL ОДИН РАЗ, а затем выполните его НЕСКОЛЬКО раз:
<?php
$Mysqli = new mysqli("host","user","pass","base");
// check connection
if(mysqli_connect_errno())
{
printf("Connect failed: %s\n",mysqli_connect_error());
exit();
}
// some data for db insertion
$countries=['Austria','Belgia','Croatia','Denmark','Estonia'];
// explicitly begin DB transaction
$Mysqli->begin_transaction();
// prepare statement (for multiple inserts) only once
$stmt=$Mysqli->prepare("INSERT INTO table(column) VALUES(?)");
// bind (by reference) prepared statement with variable $country
$stmt->bind_param('s',$country);
// load value from array into referenced variable $country
foreach($countries as $country)
{
//execute prep stat more times with new values
//$country is binded (referenced) by statement
//each execute will get new $country value
if(!$stmt->execute())
{
// rollback if prep stat execution fails
$Mysqli->rollback();
// exit or throw an exception
exit();
}
}
// close prepared statement
$stmt->close();
// commit transaction
$Mysqli->commit();
// close connection
$Mysqli->close();
?>
Ответ 4
Вы считаете, что команда "commit" автоматически переключает автообщение обратно на true? Комментарий в php doc говорит НЕТ!