Я не нашел нормального примера PHP-файла, в котором используются транзакции MySQL. Вы можете показать мне простой пример?
И еще один вопрос. Я уже много программировал и не использовал транзакции. Могу ли я поместить PHP-функцию или что-то в header.php, чтобы если один mysql_query не сработает, то и остальные — тоже?
mysql_query("SET AUTOCOMMIT=0");
mysql_query("START TRANSACTION");
$a1 = mysql_query("INSERT INTO rarara (l_id) VALUES('1')");
$a2 = mysql_query("INSERT INTO rarara (l_id) VALUES('2')");
if ($a1 and $a2) {
mysql_query("COMMIT");
} else {
mysql_query("ROLLBACK");
}
Ответ 1
Идея, которую я обычно использую при работе с транзакциями, выглядит так (полу-псевдокод):
try {
// Прежде всего давайте запустим транзакцию
$db->beginTransaction();
// Набор запросов; если один из них не работает, должно быть выброшено исключение
$db->query('first query');
$db->query('second query');
$db->query('third query');
// Если мы дошли до этого места, это означает, что исключение не возникло
// т. е. ни один запрос не завершился неудачей, и мы можем зафиксировать транзакцию
$db->commit();
} catch (\Throwable $e) {
// Возникло исключение
// Мы должны откатить транзакцию
$db->rollback();
throw $e; // но ошибка должна быть обработана в любом случае
}
Обратите внимание, что с этой идеей, если запрос не выполняется, должно быть сгенерировано исключение:
PDO может это сделать, в зависимости от того, как вы его настраиваете;
иначе, с каким-либо другим API, вам, возможно, придется протестировать результат функции, используемой для выполнения запроса, и самостоятельно выбросить исключение.
Вы не можете просто поместить где-то инструкцию и выполнять транзакции автоматически: вам все равно нужно указать, какая группа запросов должна быть выполнена в транзакции.Например, довольно часто у вас будет пара запросов перед транзакцией (до begin) и еще пара запросов после транзакции (после любого commit или rollback), и вы захотите, чтобы эти запросы выполнялись независимо от того, как выполнялся скрипт до этого.
Ответ 2
// trans.php
function begin(){
mysql_query("BEGIN");
}
function commit(){
mysql_query("COMMIT");
}
function rollback(){
mysql_query("ROLLBACK");
}
mysql_connect("localhost","Dude1", "SuperSecret") or die(mysql_error());
mysql_select_db("bedrock") or die(mysql_error());
$query = "INSERT INTO employee (ssn,name,phone) values ('123-45-6789','Matt','1-800-555-1212')";
begin(); //запуск транзакции
$result = mysql_query($query);
if(!$result){
rollback();
echo "Откат транзакции";
exit;
}else{
commit();
echo "Транзакция выполнена успешно";
}
?>
Ответ 3
Я подумал, что добавлю ответ, который явно демонстрирует, как это сделать с помощью mysqli. Вот упрощенный пример транзакций с PHP/mysqli:
// представим, что пользователь хочет создать новую "группу". мы сделаем это.
// и одновременно создадим "членство" в группе, которое
// состоит исключительно из самого пользователя (вначале). соответственно, записи о группе
// и записи о членстве должны быть созданы вместе или не создаваться вообще.
$group_name = "The Thursday Thumpers";
$member_name = "EleventyOne";
$conn = new mysqli($db_host,$db_user,$db_passwd,$db_name);
// примечание: это предназначено для таблиц InnoDB. не будет работать с таблицами MyISAM.
try {
$conn->autocommit(FALSE); // запуск транзакции
$query = "INSERT INTO groups (name) ";
$query .= "VALUES ('$group_name')";
$result = $conn->query($query);
if ( !$result ) {
$result->free();
throw new Exception($conn->error);
}
$group_id = $conn->insert_id;
$query = "INSERT INTO group_membership (group_id,name) ";
$query .= "VALUES ('$group_id','$member_name')";
$result = $conn->query($query);
if ( !$result ) {
$result->free();
throw new Exception($conn->error);
}
$conn->commit();
$conn->autocommit(TRUE); }
catch ( Exception $e ) {
$conn->rollback();
$conn->autocommit(TRUE);
}
Также имейте в виду, что в PHP 5.5 есть новый метод mysqli::begin_transaction.
Web