Задавайте вопросы, мы ответим
Вы не зашли.
Есть таблица:
CREATE TABLE xxx (f int PRIMARY KEY);
INSERT INTO xxx SET f = 2;
Затем создал транзакцию:
START TRANSACTION;
INSERT INTO xxx SET f = 10;
INSERT INTO xxx SET f = 2; // здесь ошибка.
INSERT INTO xxx SET f = 11;
COMMIT;
После выполнения COMMIT в таблице xxx присутствуют 3 строки:
+----+
| f |
+----+
| 2 |
+----+
| 10 |
+----+
| 11 |
+----+
Почему изменения фиксируются? Разве не должен происходить автоматический откат транзакции? Тип таблицы InnoDB, Сервер версии 5.1.35
Отредактированно honomer (26.06.2009 14:30:35)
Неактивен
Вы немножко не там проверяете ошибки (ошибка возникает, но Вы ее игнорируете):
Неактивен
То есть если возникла ошибка, то я должен явно вызывать ROLLBACK, а не надеятся, что сервер сам откатит транзакцию по факту возникновения ошибки?
Неактивен
Ну, если Вам проще откатить всю транзакцию, то да. Иногда бывают ситуации, когда ошибка
решается более гибко, не откатывая всю транзакцию целиком.
Более того, проверять ошибки после каждого выражения — критично. Например, в случае
deadlock Вашу транзакцию может убить (и откатить) посередине какой-то из строк, это тоже
нужно отслеживать, разумеется.
Неактивен
Наверное проще сказать что мне нужно... А нужно мне выполнить несколько операций таким образом, чтобы в случае ошибки в любом из них откатывались все предыдущие, а последующие не выполнялись. Ошибки могут возникать вследствие нарушения ограничений наложенных на столбцы таблиц, в которые пользователь вводит новые данные. То есть нужно реализовать своего рода защиту от дурака. Проверил такую ситуацию на MS SQL Server. Там тоже нет автоотката транзакции. Но зато там можно весь блок операторов заключить в конструкцию TRY. А вот на MySQL так уже не получается. Интересно есть способ вывернуться и не делать проверок после каждого оператора внутри транзакции или все же придется?
Отредактированно honomer (26.06.2009 22:41:48)
Неактивен
Я бы попробовал это сделать через обработчик событий: обработчик
вешается на ожидаемое событие (например, duplicate key), и он может
откатить всю транзакцию.
Неактивен