Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
15-1254345618
Германн
2009-10-01 01:20
2009.11.29
Интересные системные требования.


2-1255596140
Маркабес
2009-10-15 12:42
2009.11.29
SQL


3-1230041769
ВованХ
2008-12-23 17:16
2009.11.29
Сортировка записей по текстовому полю в кириллице


1-1225824956
vik2008
2008-11-04 21:55
2009.11.29
Кодировка в RX Lib


4-1223552958
тимохов
2008-10-09 15:49
2009.11.29
Как снять метрики (размеры) элементов Radio button а,





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский