SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 26.06.2009 14:11:32

honomer
Участник
Зарегистрирован: 26.06.2009
Сообщений: 16

Транзакции???

Есть таблица:

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)

Неактивен

 

#2 26.06.2009 15:19:54

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Транзакции???

Вы немножко не там проверяете ошибки (ошибка возникает, но Вы ее игнорируете):

[aquatica] root test > CREATE TABLE xxx (f int PRIMARY KEY) ENGINE=InnoDB;
Query OK, 0 rows affected (0,08 sec)

[aquatica] root test > INSERT INTO xxx SET f = 2;
Query OK, 1 row affected (0,02 sec)

[aquatica] root test > START TRANSACTION;
Query OK, 0 rows affected (0,00 sec)

[aquatica] root test > INSERT INTO xxx SET f = 10;
Query OK, 1 row affected (0,00 sec)

[aquatica] root test > INSERT INTO xxx SET f = 2;
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'
[aquatica] root test > INSERT INTO xxx SET f = 11;
Query OK, 1 row affected (0,00 sec)

[aquatica] root test > COMMIT;
Query OK, 0 rows affected (0,02 sec)

[aquatica] root test > SELECT * FROM xxx;
+----+
| f  |
+----+
|  2 |
| 10 |
| 11 |
+----+
3 rows in set (0,00 sec)

Неактивен

 

#3 26.06.2009 15:32:24

honomer
Участник
Зарегистрирован: 26.06.2009
Сообщений: 16

Re: Транзакции???

То есть если возникла ошибка, то я должен явно вызывать ROLLBACK, а не надеятся, что сервер сам откатит транзакцию по факту возникновения ошибки?

Неактивен

 

#4 26.06.2009 18:02:48

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Транзакции???

Ну, если Вам проще откатить всю транзакцию, то да. Иногда бывают ситуации, когда ошибка
решается более гибко, не откатывая всю транзакцию целиком.

Более того, проверять ошибки после каждого выражения — критично. Например, в случае
deadlock Вашу транзакцию может убить (и откатить) посередине какой-то из строк, это тоже
нужно отслеживать, разумеется.

Неактивен

 

#5 26.06.2009 21:55:46

honomer
Участник
Зарегистрирован: 26.06.2009
Сообщений: 16

Re: Транзакции???

Наверное проще сказать что мне нужно... А нужно мне выполнить несколько операций таким образом, чтобы в случае ошибки в любом из них откатывались все предыдущие, а последующие не выполнялись. Ошибки могут возникать вследствие нарушения ограничений наложенных на столбцы таблиц, в которые пользователь вводит новые данные. То есть нужно реализовать своего рода защиту от дурака. Проверил такую ситуацию на MS SQL Server. Там тоже нет автоотката транзакции. Но зато там можно весь блок операторов заключить в конструкцию TRY. А вот на MySQL так уже не получается. Интересно есть способ вывернуться и не делать проверок после каждого оператора внутри транзакции или все же придется?

Отредактированно honomer (26.06.2009 22:41:48)

Неактивен

 

#6 29.06.2009 10:46:40

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Транзакции???

Я бы попробовал это сделать через обработчик событий: обработчик
вешается на ожидаемое событие (например, duplicate key), и он может
откатить всю транзакцию.

Неактивен

 

#7 29.06.2009 17:13:44

honomer
Участник
Зарегистрирован: 26.06.2009
Сообщений: 16

Re: Транзакции???

Спасибо!

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson