Я много лет использую MySQL, но не имею большого опыта использования движка InnoDB.
Сейчас я запускаю некоторые тесты, так как я собираюсь использовать его и из того, что я прочитал, он не должен позволять чему-либо «проходить», если есть какие-либо проблемы с любым запросом в транзакции THAT.
Поэтому мой вопрос заключается в том, почему в приведенном ниже коде …. он все еще вводит первые два запроса в базу данных, когда есть явная проблема с третьим запросом?
$query = "BEGIN"; mysql_query($query); $query = "INSERT INTO list_columns(lid,column_name) VALUES(8,'test')"; mysql_query($query); $query = "INSERT INTO list_columns(lid,column_name) VALUES(8,'test')"; mysql_query($query); $query = "INSERT INT list_columns(lid,column_name) VALUES(8,'test')"; mysql_query($query); $query = "COMMIT"; mysql_query($query);
Редактирование: я понимаю об использовании ROLLBACK & all ….., но я думал, что вся цель транзакций такова, что если бы были какие-либо проблемы с любыми запросами в транзакции, тогда НИ ОДИН из них не был бы выполнен … или это только случай с несколькими вставками в одном запросе, например …. если одна из вставок представляет проблему, то никто не будет вставлен?
Чтобы добавить к тому, что сказал Konerak … это упрощенный процесс с PDO вместо mysql
например:
$pdo = new PDO($mysqldsn, $user, $pass); $pdo->beginTransaction(); try { $pdo->query("INSERT INTO list_columns(lid,column_name) VALUES(8,'test')"); $pdo->query("INSERT INTO list_columns(lid,column_name) VALUES(8,'test')"); $pdo->query("INSERT INT list_columns(lid,column_name) VALUES(8,'test')"); $pdo->commit(); } catch (PDOException $e) { $pdo->rollBack(); throw $e; }
Если проблема – это что-то вроде « Эта вставка нарушила уникальный ключ », фиксация будет иметь место. Вы должны проверить себя, если запрос возвратил ошибки, и если да, ROLLBACK
.
Если проблемой является, например, неожиданное завершение работы сервера, запросы 1 и 2 не будут выполняться.
Offcourse, так как ваши 3 вопроса здесь одинаковы, это глупый пример. По крайней мере, измените lid
чтобы ее увидеть. Почему бы вам не сделать быстрый тест?
Цель транзакций – действительно поддерживать базу данных в согласованном состоянии (чтение ACID ), но программист должен решить, что является последовательным. Посмотрите на ответ prodigitalson, чтобы увидеть пример возможного php-пути обнаружения ошибок, который делает это для вас. Но пока вы находитесь в транзакции, другие процессы не будут видеть изменений, которые совершает ваша транзакция, – следовательно, атомной и изолированной.
CREATE TABLE `testkeys` ( `lid` INT, `column_name` VARCHAR(50), UNIQUE KEY `testuniq` (`lid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; BEGIN; INSERT INTO testkeys(lid,column_name) VALUES(1,'test 1'); INSERT INTO testkeys(lid,column_name) VALUES(2,'test 2'); INSERT INTO testkeys(lid,column_name) VALUES(3,'test 3'); INSERT INTO testkeys(lid,column_name) VALUES(2,'test 2b'); COMMIT;
Вы должны проверить его вручную, и если есть какая-либо ошибка, вам нужно отменить его самостоятельно.