Форум: "Начинающим";
Текущий архив: 2009.11.29;
Скачать: [xml.tar.bz2];
ВнизНужна ли проверка InTransaction в однопоточном приложении? Найти похожие ветки
← →
И. Павел (2009-10-13 11:57) [0]Здравствуйте!
В коде дописываемой мною программы обращение к базе везде выполняется так:
if not DataMod.ADOConnection1.InTransaction then
begin
DataMod.ADOConnection1.BeginTrans;
try
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add("…
…
DataMod.ADOConnection1.CommitTrans;
except
DataMod.ADOConnection1.RollbackTrans;
end;
Создания дополнительных потоков не нашел.
Подскажите, пожалуйста, имеет ли смысл вставлять тут “if not DataMod.ADOConnection1.InTransaction then” или предыдущий программист просто выдрал это из какого-то примера и везде копировал? Думаю, что ADOConnection1.InTransaction показывает только транзакции, совершаемые текущей программой (или все же всеми), и тогда InTransaction всегда будет false если приложение однопоточное?
← →
Медвежонок Пятачок © (2009-10-13 12:16) [1]с многопоточностью это никак не связано
← →
Dennis I. Komarov © (2009-10-13 12:38) [2]Ответ на вопрос нужно или нет скрывается в строках между try и Commit
← →
И. Павел (2009-10-13 13:12) [3]
> с многопоточностью это никак не связано
Так с чем же это связано? Единственное, о чем я подумал, когда увидел этот код, что где-то может быть второй процесс, в этот же момент работающий с этой же базой, и может откатиться/подтвердиться другая транзакция...
> Ответ на вопрос нужно или нет скрывается в строках между
> try и Commit
Там повторяются конструкции вида:ADOQuery4.SQL.Clear;
ADOQuery4.SQL.Add("select/update/insert...
tru ADOQuery4.SQL.ExecSQL/Open
except on e : exception do ...
Иногда идут циклы
> while
...
ADOQuery4.Next
...
Иногда даже встречаются транзакции, всключающие только несколько select-ов, кстати, подскажите, пожалуйста, нужны ли BeginTrans и Commit/Rollback только для цепочки Select-ов, что то я совсем запутался. Вроде бы незачем...
← →
И. Павел (2009-10-13 13:20) [4]Из справки:
> Use the InTransaction property to prevent calling BeginTrans
> when a transaction has already been initiated for the connection
> component.
А если поток один и везде ошибка ловится и в except вызывается Rollback, то вроде бы InTransaction не нужен, так как вложенных BeginTrans нет...
← →
Inovet © (2009-10-13 13:43) [5]> [0] И. Павел (13.10.09 11:57)
А не путаешь ли ты try с true?
← →
И. Павел (2009-10-13 13:46) [6]
> Inovet ©
???
Вроде бы нигде true не писал.
> tru ADOQuery4.SQL.ExecSQL/Open
это просто описка, там, разумеентся, try
← →
Медвежонок Пятачок © (2009-10-13 14:04) [7]Так с чем же это связано?
Ни с чем кроме логики приложения.
Например открываем форму справочника и начинаем транзакцию.
В форме справочника открываем запись на редактирование и снова стартуем транзакцию.
Например потому что справочник программировал один программист, а редактор записи другой.
Если сервер не поддерживает вложенные транзакции, будет еррор.
Хотя поток один единственный.
Кроме того, вызывая безусловные роллбаки и коммиты ты как бы уверен на все сто что коннекшен сейчас в транзакции.
А это вовсе не обязательно.
← →
И. Павел (2009-10-13 14:15) [8]
> Медвежонок Пятачок ©
Спасибо. Но в программе старт транзакции нигде не отделен от ее завершения, тоесть логика не сложная и вложенная, а простая:
> BeginTrans;
> try
> …
> CommitTrans;
> except
> RollbackTrans;
> end;
тоесть транзакция всегда закроется, даже после ошибки, а внутри try транзакция 100% открыта, иначе бы программа вылетела до try.
Но за пример, когда, в принципе, может возникнуть ошибка, спасибо, поищу, может быть в коде действительно есть незакрывающиеся сразу транзакции...
← →
И. Павел (2009-10-13 14:22) [9]Хотя, ИМХО, лучше уж ERROR, чем тихое игнорирование встреченных SQL запросов :)
← →
Медвежонок Пятачок © (2009-10-13 14:24) [10]> except
> RollbackTrans;
> end;
Если транзакция в обработчике уже не активна, то будет еще один эксепшен для которого у тебя трая не предусмотрено.
Пример:
Начинаем транзакцию.
Вносим изменения.
На коммите пропала связь.
Эксепшен.
в обработчике роллбачить уже нечего. точнее некого.
← →
И. Павел (2009-10-13 14:38) [11]
> Медвежонок Пятачок ©
Интересный вариант :)
И что в этом случае будет? Вылетит ошибка при выполнении Rollback?
А транзакция в итоге закроется? Или при возобновлении связи останется активна?
И самое главное: такой вариант можно как нибудь учесть в программе?
Единственное, что приходит в голову:
except
try
Rollback
except
Application.MessageBox("Нет связи");
Application.Terminate;
end;
end;
← →
Медвежонок Пятачок © (2009-10-13 14:42) [12]Единственное, что приходит в голову:
except
try
Rollback
except
Application.MessageBox("Нет связи");
Application.Terminate;
end;
end;
Ты так ничего и не понял.
Откуда уверенность, что роллбак вызвал исключение потому что нет связи?
Она например есть, но на сервере роллбак сегмент закончился и он ее откатить не может (это одна из тысячи возможных причин)
← →
И. Павел (2009-10-13 15:06) [13]Кажется теперь понял:
if not DataMod.ADOConnection1.InTransaction
как раз проверяет ситуацию, если Rollback отказал и транзакция не завершилась. SQL 2005 ругается на вложенную транзакцию: "В данном сеансе невозможен запуск дополнительных транзакций", так что, наверное, лучше не писатьif not DataMod.ADOConnection1.InTransaction
чтобы вылетала ошибка, и пользователь понимал, что запрашиваемая операция не выполнилась. Иначеif not DataMod.ADOConnection1.InTransaction
просто будет молчать и ничего не делать.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.11.29;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.005 c