Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вопрос о транзакции 
:(
    Опции темы
UsamaBrainLaden
Дата 21.11.2008, 20:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 10.11.2008

Репутация: нет
Всего: нет



Имеется следующая транзакция (просто тест):
Код

SET AUTOCOMMIT = 0;
START TRANSACTION;
INSERT INTO t VALUES (1);
INSERT INTO t VALUES (1);
COMMIT;


Как видно из вышеприведённого кода в таблицу t добавляются две записи, предположим, что в этой таблице есть только одно поле причем оно должно быть уникальным. Тогда получается первая запись добавиться, а вторая уже не сможет! и при этом MySQL выдаст сообщение об ошибке и потом просто продолжит работу транзакции, а именно сохранит все изменения COMMIT'ом. И в итоге в таблице будет одна запись, хотя для положительного исхода эксперимента таблица должна быть пустой (изначально, до эксперимента таблица была пусой). Как-то не по русски получается, дело в том что нужно тогда отслеживать выполнение команд в транзакции и в случае неудачи в конце ставить ROLLBACK и в противном COMMIT. Скажем заводить какую-то логическую переменную которая бы содержала результат выполнения а в конце в зависимости от ее значения транзакция сохраняла бы изменения или откатывала. Как бы это сделать (на этом примере)?

ЗЫ:
Нельзя же тупо после транзакции писать COMMIT или ROLLBACK, это действие должно же быть условным, т.е. если транзакция прошла успешно, то COMMIT в противном случае ROLLBACK!

Это сообщение отредактировал(а) UsamaBrainLaden - 21.11.2008, 20:21
PM MAIL   Вверх
sir_nuf_nuf
Дата 21.11.2008, 22:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 8
Всего: 31



UsamaBrainLaden,  какой движок ? Транзакиции есть не во всех engine. Если движок с транзакциями (InnoDB например), то все будет работать "по - русски".  
хм.. не будет. читайте ниже

Это сообщение отредактировал(а) sir_nuf_nuf - 22.11.2008, 18:30


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
UsamaBrainLaden
Дата 21.11.2008, 23:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 10.11.2008

Репутация: нет
Всего: нет



innoDB таблицы, просто забыл указать)
PM MAIL   Вверх
sir_nuf_nuf
Дата 22.11.2008, 13:54 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 8
Всего: 31



UsamaBrainLaden, да, сделано действительно криво (как и многое в mysql)
вот что я выяснил:

1) Сервер MySQL (InnoDB) не всегда откатывает транзакцию при возникновении ошибки. В большинстве случаев откатывает только один statement (в котором была ошибка). Подробнее можно
почитать в описании InnoDB

2) Разработчики рассматривают это не как баг, а как фича-реквест

3) По сути, ответственность за откат транзакции в случае ошибки в одном из statementов - ложится на клиента.

Теперь, какие бывают клиенты:
A) mysql - в интерактивном режиме (а так же всякие QueryBrowser и т.п.)
B) mysql - в скриптовом режиме
C) через API (например DBI, JDBC и т.п.)


A) Если работаем в интерактивном режиме mysql (ну т.е. руками) - все так как вы говорили - транзакция не реагирует на ошибки. Предполагается, что вы сделаете rollback руками, когда увидите ошибку. На мой взгляд - убого.. (тем более в PostgreSQL работает как и ожидалось)
Код

mysql> create table test (a int primary key) engine=InnoDB;
Query OK, 0 rows affected (0.11 sec)

mysql> set autocommit = 0;
Query OK, 0 rows affected (0.02 sec)

mysql> select * from test;
Empty set (0.00 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test value (1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into test value (1);
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test;
+---+
| a |
+---+
| 1 |
+---+
1 row in set (0.00 sec)



2) работаем в скриптовом режиме. 
Это наш скрипт.
Код

[nuf@nuf:~]$ cat 1.sql
drop table if exists test;
create table test (a int primary key) engine=InnoDB;
set autocommit = 0;
begin;
insert into test value (1);
insert into test value (1);
insert into test value (10);
commit;
begin;
insert into test value (20);
commit;


теперь запускаем
Код

[nuf@nuf:~]$ mysql -unuf -p******* nuf < 1.sql
ERROR 1062 (23000) at line 6: Duplicate entry '1' for key 'PRIMARY'
[nuf@nuf:~]$ mysql -unuf -p******* -e 'select * from test' nuf


Как видим mysql в скриптовом режиме при возникновении ошибки откатывает транзакицю. Но это достигается прерыванием скрипта. Если запускать с ключом -f - то все будет как в интерактивном режиме.

C) DBI и прочие интерфейсы.. Тут все на совести разработчиков DBI.
В DBI можно
$dbh->{AutoCommit} = 0;
$dbh->{RaiseError} = 1;
тогда при возникновении ошибки можно перехватить perl exception и откатить транзакцию.


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
UsamaBrainLaden
Дата 22.11.2008, 18:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 10.11.2008

Репутация: нет
Всего: нет



Спасибо, доступно!
Очень конечно печально, так мне нравился MySQL, уже в нем разобрался и такой вот болт! и с CHECK и с этим. Просто если мне переходить на Postgress, то коннектится к нему мне прийдется через ADO и ODBC драйвер (это я про Delphi), потому что DBExpress не поддерживает Postgress. И я недавно пытался поставить Postgress, так понравилась установка, все так четко ставилось (гибкая инсталляха), а потом запускаю и болт! служба ни в какую не хочет работать. Можешь подскажете какойнить стабильный дистрибутив под Win32, желательно чтобы без платформы .NET?
PM MAIL   Вверх
sir_nuf_nuf
Дата 22.11.2008, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 8
Всего: 31



UsamaBrainLaden, я не спец по постгресс. Я думаю на каком-нть форуме по постгресс - вы решите проблему.

а то, что болт с mysql.. ну да. Я что-то со временем склоняюсь к мнению, что MySQL - это просто Storage, система хранения, соответсвенно требовать от нее понтов типа Exceptions, Сheck и т.п. - не имеет смысла. Зато это быстрая и проверенная система хранения =)

Если для вас не критична нагрузка и вы не собираетесь ничего реплицировать (Delphi - вроде не для нагрузки ? =)) то стоит попробовать более функциональную БД.


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0438 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.