Вниз
Скачать: CL | DM;

Транзакция как бы глючит   Найти похожие ветки 

← →
Fishka   (2004-04-09 10:25) [0]

Имеется запрос типа (ADOQuery, ADOConnection используется):
begin transaction T1;
declare ....
insert into A1 ....
if @@Error<>0 begin .... GOTO ERR_TR end
insert into A2 ....
if @@Error<>0 begin .... GOTO ERR_TR end
insert into A3 ....
...........................
if @@Error<>0 begin .... GOTO ERR_TR end
COMMIT TRANSACTION T1;");
ERR_TR: begin IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION T1;
BEGIN TRANSACTION T2;
update ....
COMMIT TRANSACTION T2;
end;

На форме есть AdoDataSet, поле которого отображается в DBRichEdit. Если два оператора случайно редактируют одновременно одну и ту же запись (DBRichEdit), то для второго оператора при попытке обработать эту запись (т.е. нажать кнопку, где идет приведенный выше запрос) выдается сообщение типа "запись была уже изменена" и далее невозможно даже уйти с данной записи, можно только закрыть форму. И при в таблицу А2 вносится запись, хотя в таблицу А1 запись не добавляется. И соответственно, нарушается целостность базы.  
Вопрос:  как избежать такой ситуации? Может быть, неверно установлены свойства используемых компонентов?


← →
Nikolay M. ©   (2004-04-09 10:38) [1]

Имхо, не зная, какие именно данные редактируются, что конкретно постится, какие ключевые поля в каких таблицах, по вышеприведенному куску трудно что-то сказать.
ПолтерГейтс.


← →
bushmen ©   (2004-04-09 10:40) [2]

Что-то у тебя кривовато написано. Конструкция "if ... begin"
не будет работать без "end". Либо пиши код полностью, либо вряд ли кто-то поймет, что ты написал


← →
Nikolay M. ©   (2004-04-09 10:58) [3]


> "if ... begin" не будет работать без "end".

Как раз у "if ... begin" end есть, а вот у "begin ... if" - нет.


← →
Delirium ©   (2004-04-09 11:01) [4]

С точки зрения MSSQL всё работает правильно, но ты делаешь ошибку в том, что не используешь механизм обработки транзакций самих ADO. У TADOConnection есть методы вызова, применения и отката транзакций, именно ими в купе с try except и надо пользоваться, чтобы ADO "понимали" что ты делаешь.


← →
Nikolay M. ©   (2004-04-09 11:03) [5]


> делаешь ошибку в том, что не используешь механизм обработки
> транзакций самих ADO. У TADOConnection есть методы вызова,
> применения и отката транзакций, именно ими в купе с try
> except и надо пользоваться, чтобы ADO "понимали" что ты
> делаешь.

А я бы наоборот с клиента все транзакции убрал и реализовал их разруливание в хранимых.


← →
Delirium ©   (2004-04-09 11:07) [6]

"А я бы наоборот с клиента все транзакции убрал" - это было бы самое лучшее решение, описать бизнес-правила в виде хранимых процедур и заложить всю транзакционность туда. Это более системный и грамотный подход вообще, но ведь автора волновала проблема работы с транзакциями на клиенте и с использованием ADO.


← →
Fishka   (2004-04-09 11:12) [7]

Это кусок кода. Код полностью предполагает вставку в более чем 20 таблиц. Конструкция "if ... begin" написана верно. В день обрабатывается более 200 записей, и если операторы не встречаются на одной записи, то все нормально. Так что описанная выше ситуация бывает редко, но бывает.
Не понимаю, какое отношение имеет текст запроса, ведь он работает верно.


← →
bushmen ©   (2004-04-09 11:29) [8]

Да, а end я не увидел. Старею :))


← →
Nikolay M. ©   (2004-04-09 11:39) [9]


> автора волновала проблема работы с транзакциями на клиенте
> и с использованием ADO.

Ну да, автор сделал, а нам - телепатировать :)

Хотя бы скажи, в какой момент этот запрос запускается :)
Я подозреваю, что он у тебя меняет значение некоторых ключевых полей, по которым идет апдейт и когда второй оператор пытается запостить данные запросом вроде
UPDATE tablename SET RichEditField = "bla-bla" WHERE SomeField = XXX
он обламывается, потом как в поле SomeField значение XXX потерлось первым оператором на какое-нибудь YYY.


← →
Nikolay M. ©   (2004-04-09 11:40) [10]


> обламывается, потом как в поле SomeField

...потому как в поле SomeField...


← →
Fishka   (2004-04-09 12:02) [11]

Телепатировать не надо.
При нажатии на кнопку сначала удаляется запись из всех таблиц (запрос DELETE from A1 where ....). Затем при нажатии на кнопку идет приведенный выше запрос с многими INSERT-ами. Update нет вообще.
Да, меня волнует проблема работы с транзакциями на клиенте
и с использованием ADO.


← →
Johnmen ©   (2004-04-09 12:11) [12]

>Delirium ©   (09.04.04 11:07) [6]
>...заложить всю транзакционность туда. Это более системный и
>грамотный подход вообще ...

"Вообще" - это для MSSQL ?

Я бы сказал, что это ("транзакционность туда"), подход в корне неверный, не зависимо от типа SQL сервера...


← →
Nikolay M. ©   (2004-04-09 12:13) [13]


> Update нет вообще.


> BEGIN TRANSACTION T2;
> update ....
> COMMIT TRANSACTION T2;

А это тогда что?
И как сочетается "нажатие на кнопку" (как я понимаю, ручной апдейт полей) и использование DB-aware компонент? Что происходит с ADOQuery после того, как в DBRichEdit было отредактировано некоторое поле и нажата кнопка? ADOQuery.Cancel? .Post?


← →
Nikolay M. ©   (2004-04-09 12:16) [14]


> Я бы сказал, что это ("транзакционность туда"), подход в
> корне неверный, не зависимо от типа SQL сервера...

Аргументы - ? Было бы интересно их услышать в зависимости от типа клиента - тонкий или для клиент-сервера. If you don`t mind, sir...


← →
Fishka   (2004-04-09 12:22) [15]

В TRANSACTION T2 есть Update, но он тут ни при чем, а в TRANSACTION T1 нет Update вообще.
В DBRichEdit отображается значение поля, в котором текст, который по определенным правилам нужно разнести по таблицам.
После того, как в DBRichEdit было отредактировано некоторое поле и нажата кнопка, происходит ADOQuery.Cancel или .Post в зависимости от ответа оператора и далее идет INSERT, описанный выше.


← →
Nikolay M. ©   (2004-04-09 12:26) [16]


> После того, как в DBRichEdit было отредактировано некоторое
> поле и нажата кнопка, происходит ADOQuery.Cancel или .Post

И не при Post-е ли происходит та самая ошибка?


← →
Fishka   (2004-04-09 12:34) [17]

При Post-е, может и происходит ошибка и выдается сообщение о том, что запись была изменена. Но откуда  появляется запись в таблице А2  запись, хотя в таблицу А1 запись не добавляется?


← →
Nikolay M. ©   (2004-04-09 12:39) [18]


> откуда  появляется запись в таблице А2  запись, хотя в таблицу
> А1 запись не добавляется?

Это уже смотри свою логику, чудес не бывает. Может, у тебя на А2 триггер, который коцает А1, например.


> При Post-е, может и происходит ошибка и выдается сообщение
> о том, что запись была изменена.

Что и требовалось доказать...


← →
Delirium ©   (2004-04-09 12:49) [19]

> Johnmen ©   (09.04.04 12:11) [12]

"Я бы сказал, что это ("транзакционность туда"), подход в корне неверный, не зависимо от типа SQL сервера..." - т.е. что ты имеешь в виду? Что бизнес-правило овормленное в хранимую процедуру должно быть лишено транзакционности? Как ты это видишь?
Оборачивать саму прцедуру в транзакцию и анализировать результат? А смысл работы процедуры основывается на нескольких транзакционно-разделённых процессах, пикажете каждый отдельный процесс в свою процедуру оборачивать?


← →
Johnmen ©   (2004-04-09 13:16) [20]

>Delirium ©   (09.04.04 12:49) [19]

>Что бизнес-правило овормленное в хранимую процедуру должно быть
>лишено транзакционности? Как ты это видишь?

Нет, не лишено. Но в контексте текущей тр-ии.
Бизнес-правила и тр-ии есть разные "сущности".

>А смысл работы процедуры основывается на нескольких
>транзакционно-разделённых процессах

Это некий особый "вид" процедуры, судя по всему. Или что ты понимаешь под словом "процедура" ? Отдельный самодостаточный целостный процесс ? Или же набор приемов, реализующих б.-логику, и не более ?
Лично для меня - это второе...


← →
Delirium ©   (2004-04-09 13:36) [21]

"что ты понимаешь под словом "процедура"" - под словом процедура применительно к базам данных, я понимаю исключительно хранимую процедуру, как всегда и указываю. И в таком понимании поцедура действительно - "Отдельный самодостаточный целостный процесс", чем и хороша. Если мне требуется оформить какой-либо документ, у меня должна быть процедура модификации, которой в качестве параметров передаются данные, а результатом работы является модификация соответствующих справочников, вызов других процедур и т.п. в той последовательности и с тем уровнем целостности, какой требует бизнес-операция. Именно такой подход я и называю реализация бизнес логики на уровне хранимых процедур, если в БД все клиентские модификации осуществляются хранимыми процедурами, а запросы клиентов направлены исключительлно к представлениям - то такая БД на практике является чрезвычайно мастабируемой и не требует ни какого промежуточного слоя (сервера приложений). Для организаци малого и среднего бизнеса - идеальный вариант, существенно снижающий затраты на разработку корпоративного софта.


← →
Johnmen ©   (2004-04-09 13:53) [22]

Всё это здорово, и никто с этим как бы не спорит.
Но причем же здесь транзакционный механизм ????????


← →
Fay ©   (2004-04-09 14:01) [23]

Ключевым полям скажите InKey


← →
Delirium ©   (2004-04-09 14:09) [24]

"Но причем же здесь транзакционный механизм ????????" - как это причём? Практически в каждой серьёзной хранимой процедуре создаются и применяются транзакции, причём от результатов работы транзакций могут меняться дальнейшие действия. Получается, что клиент просто может ничего не знать ни о каких транзакциях - его задача предеть параметры поцедуре и всё, а остальное - реализовал его "старший брат", некто  - продвинутый, грамотно написавший процедуру и предусмотревший множество вариантов работы.


← →
Fishka   (2004-04-09 14:12) [25]

Вернемся к нашим баранам.
Я не знаю, как будет выглядеть транзакция через хранимые процедуры. Это сколько же TstringList-ов мне придется в них передать!
Резюме: обработка ошибки на Post, возможно, поможет мне избежать ошибки при Insert.
Хотя все-таки, непонятно, откуда берется та запись в таблице А2....


← →
Johnmen ©   (2004-04-09 14:17) [26]

Вот-вот, это уже выходит за рамки понятия ХП. Это уже нечто более "высокого" уровня.

>Практически в каждой серьёзной хранимой процедуре создаются и
>применяются транзакции

Опять же, если мы говорим о MSSQL, то так можно действовать, но это уже нечто большее, чем просто ХП, идеологически. И это обеспечивается расширенным механизмом, именно механизмом, функционирования ХП. (ура:) Биллу :))
Если мы говорим о SQL серверах вообще, то неужели ты считаешь, что, напр. для IB SQL сервера, нельзя написать серьёзную ХП ?


← →
Fay ©   (2004-04-09 14:17) [27]


> Это сколько же TstringList-ов мне придется в них передать!
>

А почему бы, к примеру, не TServerSocket-ов?


← →
Delirium ©   (2004-04-09 14:20) [28]

"неужели ты считаешь, что, напр. для IB SQL сервера, нельзя написать серьёзную ХП ?" - откуда такой вывод?


← →
Johnmen ©   (2004-04-09 14:30) [29]

>откуда такой вывод?

Вывод из
1. управление транзакциями в ХП (IB)
2. несерьёзность ХП без управл.тр-ми


← →
Delirium ©   (2004-04-09 15:10) [30]

Хм, ну на самом деле если сервер БД не поддерживает управление транзакциями в ХП, то этот недостаток легко компенсируется введением системы статусов, т.е. в каждую критичную таблицу добавляетя булево поле lLock и при работе все действия увязиваются с ним. Собственно можно реализовать кучу подходов с пользовательскими транзакциями и без, важно одно - принцип: вся бизнес-логика в ХП. Вот и всё :)


← →
Nikolay M. ©   (2004-04-09 16:02) [31]


> Хотя все-таки, непонятно, откуда берется та запись в таблице
> А2....

Start/Programs/MS SQL Server/Profiler не пробовал запускать? Помогает...


← →
Johnmen ©   (2004-04-09 16:13) [32]

>Delirium ©   (09.04.04 15:10) [30]
>важно одно - принцип: вся бизнес-логика в ХП. Вот и всё :)

С этим никто не спорил.
Еще раз подчеркну, что бизнес-логика к управлению тр-ми никакого отношения не имеет. А если имеет, то это уже не б.-л., а нечто более общее...

>если сервер БД не поддерживает управление транзакциями в ХП, то
>этот недостаток

Нет, не так. Это не недостаток, а то, что поддерживает - это расширение !


← →
Delirium ©   (2004-04-09 16:21) [33]

"Это не недостаток" - согласен, согласен, ни каких религиозных войн - у MSSQL не преимущество перед IB, а расширение - совершенно согласен :)


← →
Johnmen ©   (2004-04-09 16:28) [34]

О, Господи... Да нет войн никаких. Просто интересовался твоим пониманием и не более того, почти...
:)


← →
Fay ©   (2004-04-09 16:33) [35]

Попробуй так
begin transaction T1;
declare ....
insert into A1 ....
if @@Error<>0 begin .... GOTO ERR_TR end
insert into A2 ....
if @@Error<>0 begin .... GOTO ERR_TR end
insert into A3 ....
...........................
if @@Error<>0 GOTO ERR_TR
while @@trancount > 0 COMMIT TRANSACTION T1;
goto BuBuBu
ERR_TR: while (@@TRANCOUNT > 0) ROLLBACK TRANSACTION T1;
BuBuBu:BEGIN TRANSACTION T2;
update ....
COMMIT TRANSACTION T2;
end;



Страницы: 1 вся ветка

Скачать: CL | DM;



Память: 0.55 MB
Время: 0.032 c
1-1080123367
аппельсин
2004-03-24 13:16
2004.04.11
запрос к дереву


7-1075719213
Creator
2004-02-02 13:53
2004.04.11
как работать с COM портами ???


1-1082269311
Bond
2004-04-18 10:21
2004.04.11
Rave


14-1081921022
химик
2004-04-14 09:37
2004.04.11
Люди, срочно! Может кто-то скинуть мне на почту QTINTF.DLL


7-1076246345
sadretro
2004-02-08 16:19
2004.04.11
как програмно можно зашарить доступ к папке




   Наверх