![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Обработка ошибки при разрыве связи [D7, MSSQL]
Tornado © (2006-01-25 17:00:00)Есть прога работающая по сети с БД MS SQL Server. Компоненты ADOConnection+ADODataSet. При добавлении новой записи иногда в этой самой сети случаются затыки, редко но бывает. Если в процессе добавления записи возникает подробный затык в сети появляется ошибка (эта ситуация обработана и все нормально). Запись добавляется SQL-запросом, используются транзакции:
try
ADOConnection.BeginTrans;
Close;
SQL.Clear;
SQL.Add('INSERT INTO ' + Reg.ReadString('Options', 'tblShapkaName', '') + ' (YEAR_IZM, LPUMG, STOIKANUM, NACHALNIK) VALUES (:YEAR_IZM, :LPUMG, :STOIKANUM, :NACHALNIK)');
Parameters.ParamByName('YEAR_IZM').Value := cbaddYear.Text;
Parameters.ParamByName('LPUMG').Value := 'Один';
Parameters.ParamByName('STOIKANUM').Value :=cbaddStoikaNum.Text;
Parameters.ParamByName('NACHALNIK').Value := txtaddBoss.Text;
ExecSQL;
if ADOConnection.InTransaction = True then begin
ADOConnection.CommitTrans; {успешное окончание транзакции}
end
else begin
ADOConnection.RollbackTrans;
end;
except
ADOConnection.RollbackTrans;
Вообщем все хорошо, но если потом (после затыка) снова нажать кнопку "Добавить" под которой выполняется вышеприведенный код появляется ошибка: "В данном сеансе невозможен запуск дополнительных транзакций"
Вопрос как правильно обработать эту ошибку?
Tornado (2006-01-26 10:40:00) [1]спасибо всем, разобрался :)
sniknik (2006-01-26 08:56:00) [2]уточнение
транзакции имеют смысл когда вставляются данные со связями/зависимые друг от друга/ссылающиеся т.е. такие которые одна часть без другой части ничего не значат или даже приводят к нарушению целостности данных.
к примеру данные накладной (внутренности) и ее заголовок (шапка) в другой таблице если он по логике программы формируется после "внутренностей". (работа то идет после по заголовкам и если его не будет то внутренности безсмыссленны их никто, никогде не увидит. а вот на формирования отчетов каких нибудь они повлиять могут, если будут совпадаюшие признаки по которым строится отчет ... получится логический трудноуловимый глюк (попробуй найти если это например только в годовом отчете "вылазит", и притом не в самой глючной программе, а в связаной куда та данные пересылает (там как раз потоварные сквозные отчеты независимые от "шапок" делаются)))
или нормализованные записи, т.е. когда одна логически неделимая запись лежит в нескольких таблицах, и запись только одной ее части будет неинформативен по крайней мере, либо будут опять теже глюки со связями.
а вот если записей пусть и много но они независимы ни от чего, то транзакция не нужна. к примеру делаеш начальное заполнение базы, справочник товаров, запись совершенно независимая (вообще это от логики структуры базы зависит, ну у нас считай так - независимая) и нафига тут транзакция которая откатит все заполнение при неправильных/сбойных данных в например предпоследней записи (а их 170тыс ;)....? лучше уж глюк от этой записи пихнуть в лог и продолжить заполнение без всяких транзакций, в конце только выдать "были ошибки при заполнении - запись ..." пусть разбираются с каждой конкретной, а с программой в тоже время уже можно работать. (на "запусках" магазинов это ой как критично ;)
p.s. imho ADOConnection.BeginTrans; (и др.) лучше поменять на команды сервера "BEGIN TRANSACTION" и др. выполняемые в ADOCommand.
ЮЮ (2006-01-26 07:36:00) [3]В том случае, естественно, когда изменеия должны касаться или всех (более 1-ой) или не одной записи.
Т.е. когда при возникновении хотя бы одной ошибке в пакете изменений всё откатывается назад
Кто-то непонятный (2006-01-26 06:19:00) [4]
> ЮЮ ©
Извеняюсь за офтоп, а при каких обстоятельствах следовало бы управлять трансзакциями?
ЮЮ (2006-01-26 04:15:00) [5]Кстати , где здесь сабжевый "разрыв связи"?
ЮЮ (2006-01-26 03:22:00) [6]if ADOConnection.InTransaction = Truethen begin
ADOConnection.CommitTrans; {успешное окончание транзакции}
end
else begin
ADOConnection.RollbackTrans;
end;
И что здесь "откатывать", если не в транзакции? Тем более при чем здесь {успешное окончание транзакции}?
На мой взгляд, лучше так:
if not ADOConnection.InTransaction then ADOConnection.BeginTrans;
try
...
ExecSQL;
ADOConnection.CommitTrans;
except
ADOConnection.RollbackTrans;
end;
З.Ы. Зачем брать на себя управление транзакцией при вставке одной записи? Она и так либо вставится, либо - нет.