Sanya
User
 Senior Boarder
| Posts: 33 |   | Karma: 0 |
|
Глюки с транзакциями.
|
|
Posted: 2008/03/03 09:47 |
|
|
|
|
В примере по транзацции есть код:
StartTransaction;
try
mmInfo.Lines.Add(' Execute simple command inside transaction');
ADQuery1.SQL.Text := 'select * from {id Categories}';
ADQuery1.Open;
mmInfo.Lines.Add(' Commit transaction');
Commit;
except
mmInfo.Lines.Add(' Rollback transaction');
Rollback;
raise;
end;
|
Во время выполнения возникает исключительная ситуация и код попадает в except следовательно Commit не выполняется, а выполняется Rollback - как и должно быть.
Изменим код:
StartTransaction;
try
mmInfo.Lines.Add(' Execute simple command inside transaction');
ADQuery1.SQL.Text := 'select * from table1';
ADQuery1.Open;
ADQuery1.Edit;
ADQuery1.FieldByName('coll1').AsInteger := 10000;//Допустим значение которое данное поле принять не может.
ADQuery1.Post; //Здесь происходит исключение
mmInfo.Lines.Add(' Commit transaction');
Commit;
except
mmInfo.Lines.Add(' Rollback transaction');
Rollback;
raise;
end;
|
Во время выполнения возникает исключительная ситуация и код попадает в except следовательно Commit не выполняется, а выполняется Rollback – Здесь тоже все верно.
Изменим код ещё (Включим кэширование изменений):
ADQuery1.CachedUpdates := True;//Включаем кэширование
StartTransaction;
try
mmInfo.Lines.Add(' Execute simple command inside transaction');
ADQuery1.SQL.Text := 'select * from table1';
ADQuery1.Open;
ADQuery1.Edit;
ADQuery1.FieldByName('coll1').AsInteger := 10000;//Допустим значение которое данное поле принять не может.
ADQuery1.Post;
ADQuery1.ApplyUpdates();//Здесь должно пройти исключение
mmInfo.Lines.Add(' Commit transaction');
Commit;
except
mmInfo.Lines.Add(' Rollback transaction');
Rollback;
raise;
end;
|
Во время выполнения ни какой исключительной ситуации не происходит и транзакция завершается оператором Commit, секция except не выполняется. Хотя во всех случаях изменения в базе не были произведены.
Таблица Table существует на самом деле и поле coll1 тоже существует и имеет тип TINYINT(1). Если оператор ADQuery1.FieldByName('coll1').AsInteger := 10000; заменить на ADQuery1.FieldByName('coll1').AsInteger := 10; то изменения в базу нормально заносятся.
Также во время первого выполнения программы (в последнем варианте) при выполнении инструкции ADQuery1.ApplyUpdates(); Выскочило сообщение об ошибке обновления, но программа в секцию except не попала. При последующих запусках программы больше ни какого сообщения не выскакивало.
Пробовал ADQuery1.ApplyUpdates(); заменить на ADQuery1.ApplyUpdates(0); - ни какого эффекта не произвело, все осталось на том же уровне.
В Мониторе для последнего варианта проходит:
BEGIN
select * from table1
UPDATE table1SET coll1 = 10000 WHERE id = 1 AND coll1 = 10 AND coll2 = '0001'
COMMIT
|
Поле выполнения чего изменений в базе не происходит.
|
|