поэтому у меня возникают проблемы с использованием транзакций в PDO. Я делаю быстрый тест:
<?php
include_once "./init.php";
$sql = "insert into tbTest(cValue) values('1');";
$sttmt = $db->prepare($sql);
$sttmt->execute();
$sql = "SET autocommit=0;";
$sttmt = $db->prepare($sql);
$sttmt->execute();
$db->beginTransaction();
$sql = "SET autocommit=0; insert into tbTest(cValue) values('2');";
$sttmt = $db->prepare($sql);
$sttmt->execute();
$db->rollBack();
$db->beginTransaction();
$sql = "SET autocommit=0; insert into tbTest(cValue) values('3');";
$sttmt = $db->prepare($sql);
$sttmt->execute();
$db->rollBack();
?>
Моя первая вставка проходит без зуда.
Вторая вставка (в первой транзакции) получает откат. однако я начинаю другую транзакцию сразу после, снова вставляю и снова откатываюсь. Обычно я ожидал бы получить только "1" в моей таблице.
Что происходит, так это то, что 2 возвращается, но после третьей вставки я снова откатываюсь и получаю следующее сообщение об ошибке:
Неустранимая ошибка: исключить исключение "PDOException" с сообщением "Нет активной транзакции" в /home/.../.../.../testSQL.php:24 Трассировка стека: # 0/home/.../.../.../testSQL.php(24): PDO-> rollBack() # 1 {main} брошен в /home/.../.../.../testSQL.php в строке 24
теперь, пожалуйста, проигнорируйте строку #, я не включил материал html. Строка 24 - это вторая rollBack(). Один после вставки значения "3".
Я абсолютно не понимаю, что происходит. Почему первая транзакция работает, а не вторая? Моя таблица НЕ содержит "3". Я не знаю, работал ли откат несмотря на сообщение об ошибке или если autocomit = 0 помешало значению "3" сделать его в таблице... У меня нет подсказки.
У кого-то есть объяснение?
Спасибо,
как указал Найджел Рен, проблема была поставлена автокомпозитом. Таблицы MyISAM не могут управлять транзакциями. Я добавил набор автокомпонентов как часть моих тестов, когда моя таблица была MyISAM и забыла удалить ее, когда я переключился на InnoDB.
Версия, которая работает:
<?php
//not in a transaction
$sql = "insert into tbTest(cValue) values('1');";
$sttmt = $db->prepare($sql);
$sttmt->execute();
$db->beginTransaction();
$sql = "insert into tbTest(cValue) values('2');";
$sttmt = $db->prepare($sql);
$sttmt->execute();
$db->rollBack();
$db->beginTransaction();
$sql = "insert into tbTest(cValue) values('3');";
$sttmt = $db->prepare($sql);
$sttmt->execute();
$db->commit();
//not in a transaction
$sql = "insert into tbTest(cValue) values('4');";
$sttmt = $db->prepare($sql);
$sttmt->execute();
$db->beginTransaction();
$sql = "insert into tbTest(cValue) values('5');";
$sttmt = $db->prepare($sql);
$sttmt->execute();
$db->rollBack();
//not in a transaction
$sql = "insert into tbTest(cValue) values('6');";
$sttmt = $db->prepare($sql);
$sttmt->execute();
?>
Только значения 1, 3, 4 и 6 попадают в таблицу. Это ожидаемые результаты!
Еще раз спасибо Найджелу Рену!