Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.12.07;
Скачать: CL | DM;

Вниз

Транзакции в ADO   Найти похожие ветки 

 
Hiller   (2008-05-15 17:38) [0]

Здравствуйте, коллеги!
Раньше никогда не работал в АДО, а вот пришлось.
Проблема такая, при старте транзакции пишет
---------------------------
Debugger Exception Notification
---------------------------
Project prjPersonal.exe raised exception class EOleException with message "Не удается создать новую транзакцию из-за превышения допустимой емкости". Process stopped. Use Step or Run to continue.
---------------------------
OK   Help  
---------------------------

Код, где это происходит следующий:

===
dbMain: TADOConnection;
quDBUpdate: TADOQuery;
dmDatabase - форма с компонентами
===


function DoSQL(aSQL: string): integer;
begin
 dmDatabase.quDBUpdate.SQL.Text := aSQL;
 result := dmDatabase.quDBUpdate.ExecSQL;
end;

procedure DoDBUpdate(aNum: integer; aSQL: string);
begin
 if dmDatabase.dbMain.Connected then   //Здесь все нормально,  
                                                       //соединение установлено
 dmDatabase.dbMain.BeginTrans; //Вот здесь падает, ага
 try
   if not WasUpdate(aNum) then
   begin
     DoSQL(aSql);
     DoSQL("INSERT INTO VERSION (VERSION_NUM, UPDATE_DATE) VALUES (" + IntToStr(aNum) + ", GETDATE())");
   end;
 except
   dmDatabase.dbMain.RollbackTrans;
   raise
 end;
 dmDatabase.dbMain.CommitTrans;
end;

Дельфя седьмая, БД MSSQL.
Помогите, кто чем может :)


 
BoxTer   (2008-05-16 07:42) [1]

ConnectionString какой?


 
Hiller   (2008-05-16 09:40) [2]

Provider=SQLOLEDB.1;Password=personal;Persist Security Info=True;User ID=personal;Initial Catalog=KADR;Data Source=W1824


 
Hiller   (2008-05-16 09:46) [3]

Извиняюсь, обманул :(
"Provider=SQLOLEDB.1;Password=personal;Persist Security Info=True;User ID=PERSONAL;Initial Catalog=OKIPO;Data Source=W1824;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=W1824;Use Encryption for Data=False;Tag with column collation when possible=False"


 
BoxTer   (2008-05-16 10:04) [4]

А IsolationLevel коннекшна?


 
Hiller   (2008-05-16 10:06) [5]

ilReadCommitted


 
BoxTer   (2008-05-16 10:11) [6]

Поставьте ilReadUnCommitted


 
BoxTer   (2008-05-16 10:17) [7]

В вашем уровне изоляции(ilReadCommitted) перед началом новой транзакции имеет смысл добавить
if not Connection.InTransaction
   then Connection.BeginTrans
   else Connection.CommitTrans;


 
Кщд   (2008-05-16 10:22) [8]

>BoxTer   (16.05.08 10:17) [7]
безусловно commit"ить открытую транзакцию - на мой взгляд, не самая лучшая рекомендация


 
BoxTer   (2008-05-16 10:26) [9]

Канешна довести до ума нужно, главное смысл я передал :)


 
Ega23 ©   (2008-05-16 10:28) [10]

Там и в логике ещё ошибка. Если not dmDatabase.dbMain.Connected, то по-любому Commit будет делаться.


 
Hiller   (2008-05-16 10:42) [11]


> BoxTer   (16.05.08 10:17) [7]
>
> В вашем уровне изоляции(ilReadCommitted) перед началом новой
> транзакции имеет смысл добавить
> if not Connection.InTransaction

Там никогда не должно быть InTransaction


> Ega23 ©   (16.05.08 10:28) [10]
>
> Там и в логике ещё ошибка. Если not dmDatabase.dbMain.Connected,
>  то по-любому Commit будет делаться.

Это тестовая строка, чтобы убедиться что соединение установлено. В этом месте оно должно быть всегда.

Да, и еще - разве АДО не поддерживает вложенность транзакций?


 
Ega23 ©   (2008-05-16 10:48) [12]


> Это тестовая строка, чтобы убедиться что соединение установлено.
>  В этом месте оно должно быть всегда.


Только не в таком виде.

if not dmDatabase.dbMain.Connected then Exit;

Сейчас пересмотрел код, первый раз raise не заметил. Логической ошибки нет, но всё равно - лишние exception-ы. Зачем?


 
BoxTer   (2008-05-16 10:56) [13]


> Там никогда не должно быть InTransaction

Ну дык там нет, в другом месте будет :)
Проблема решилась?


 
sniknik ©   (2008-05-16 11:09) [14]

> Логической ошибки нет
есть.

> if not WasUpdate(aNum) then
допустим условие функции true...

> Да, и еще - разве АДО не поддерживает вложенность транзакций?
ADO счтиай вообще ничего не поддерживает... все делает сервер, а ADO просто передает ему команды. (ну, не все так просто конечно, но прими это за основу)
именно поэтому не пользуюсь сам и не рекомендую другим пользоваться транзакциями от компонент (мало ли чего напередает), предпочитаю выполнять команды сам, явно.

+ транзакция в данном случае не нужна вообще, достаточно составить пакет из 2х команд, все одно они у тебя динамические и компилятся всегда заново, и mssql сам "обернет" этот пакет неявной транзакцией.
т.е. убираешь все связанное с транзакциями и оставляешь
DoSQL(aSql + #13#10"INSERT INTO VERSION (VERSION_NUM, UPDATE_DATE) VALUES (" + IntToStr(aNum) + ", GETDATE())");
exception и ре-raise тоже тогда не нужны.


 
версия для печати   (2008-05-16 11:12) [15]


> Да, и еще - разве АДО не поддерживает вложенность транзакций?


а что это такое


 
sniknik ©   (2008-05-16 11:18) [16]

> function DoSQL(aSQL: string): integer;
идиотский метод...

уж если приспичило, то делаешь у конекта Execute(aSQL).

строка в [2], более "правильная", в [3] это явно при открытом конекте, чего делать в дизигне не стоит (в смысле держать открытым, чтобы он сам открывался при запуске программы).


 
Hiller   (2008-05-16 11:57) [17]


> BoxTer   (16.05.08 10:56) [13]
>
>
> > Там никогда не должно быть InTransaction
>
> Ну дык там нет, в другом месте будет :)
> Проблема решилась?

Нет, все тоже самое :(


>
> + транзакция в данном случае не нужна вообще, достаточно
> составить пакет из 2х команд, все одно они у тебя динамические
> и компилятся всегда заново, и mssql сам "обернет" этот пакет
> неявной транзакцией.
> т.е. убираешь все связанное с транзакциями и оставляешь
> DoSQL(aSql + #13#10"INSERT INTO VERSION (VERSION_NUM, UPDATE_DATE)
> VALUES (" + IntToStr(aNum) + ", GETDATE())");
> exception и ре-raise тоже тогда не нужны.

Чувствуется профи, спасибо, попробую :)


> > function DoSQL(aSQL: string): integer;
> идиотский метод...
>
> уж если приспичило, то делаешь у конекта Execute(aSQL).

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

>
> строка в [2], более "правильная", в [3] это явно при открытом
> конекте, чего делать в дизигне не стоит (в смысле держать
> открытым, чтобы он сам открывался при запуске программы).
>
>

А оно так и есть - строка в[2] это состояние в дезайнтайме, строка в [3] - в рунтайме в момент выполнения указаного кода. Извиняюсь за то, что невольно ввел в заблуждение.


 
sniknik ©   (2008-05-16 12:35) [18]

> С этим извини, не согласен. Всегда делаю функции-обертки.
и закрываешь себе возможность нормальной работы с параметрами... либо начинаешь городить еще и их передачу в такую функцию, путаешься естественно, + заставляешь сервер постоянно перекомпилять запросы т.к. он динамические. и не дай Гейтс. попадет такая обертка в цикл, начинаются "вопли" какой тормозной этот ваш ADO и т.д.. другие проблемы.
а их могло бы и не быть пиши ты правильно, пусть на 1 строчку в некоторых местах и больше.
экономишь строчки, теряешь производительность.

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

p.s. это конечно домыслы, сугубое имхо так сказать, может ты и пишешь правильно там где надо, а это используешь только подходящих под него местах. но... много раз уже видел подобное, и всегда стиль "растягивается" на все, т.е. "если увидел чайку, то и море рядом...".


 
Hiller   (2008-05-16 13:20) [19]


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

Погоди, я не понял. Ты имеешь ввиду, что лучше В ЭТОЙ ФУНКЦИИ использовать внешнюю текстовую константу с запросом вместо того чтобы переопределять свойство SQL у компоненты, так? Я тебя понял так, что нужно вместо сервисной функции везде делать явный вызов метода. И именно с этим был не согласен.


> > в будущем весьма вероятно расширение функциональности.
>
> до стандартной, уже имеющейся у ADO компонент функциональности
> тебе ее и за год не довести...

А это видимо ты не понял :) Я не собираюсь изобретать велосипед и переписывать компонент. Я просто забиваю на будущее возможность добавить какие-либо действия перед/после выполнения запроса. Если это не сделать, потом надо будет найти в коде все места, где выполнялся запрос, а так достаточно внести изменения в сервисную функцию.


 
sniknik ©   (2008-05-16 13:59) [20]

> Погоди, я не понял. Ты имеешь ввиду, что лучше В ЭТОЙ ФУНКЦИИ использовать внешнюю текстовую константу с запросом вместо того чтобы переопределять
> свойство SQL у компоненты, так? Я тебя понял так, что нужно вместо сервисной функции везде делать явный вызов метода. И именно с этим был не согласен.

вот изза этой фигни
> " + IntToStr(aNum) + "
запрос становиться динамическим и перекомпиляется сервером каждый раз перед выполнением,
правильно статически прописать запрос, а меняемую часть сделать параметром. причем твоя функция прямо таки навязывает стиль с изменением запроса, вместо параметров (передается строка запроса).
не показан способ формирования первого запроса
> procedure DoDBUpdate(aNum: integer; aSQL: string);
но могу "забиться" на то что там тот же стиль, с переменными сделанными частью запроса...
вот это вот я и называю идиотским подходом. неважно с чем ты там несогласен.

> Я не собираюсь изобретать велосипед и переписывать компонент.
поздравляю, хоть и не хотел, но начал.

> а так достаточно внести изменения в сервисную функцию.
вот вот. привычка к своему велосипеду уже сказывается. вместо того чтобы изыскать методы при нормальной работе.


 
Hiller   (2008-05-16 15:19) [21]


>
> вот изза этой фигни
> > " + IntToStr(aNum) + "
> запрос становиться динамическим и перекомпиляется сервером
> каждый раз перед выполнением,
> правильно статически прописать запрос, а меняемую часть
> сделать параметром. причем твоя функция прямо таки навязывает
> стиль с изменением запроса, вместо параметров (передается
> строка запроса).
> не показан способ формирования первого запроса
> > procedure DoDBUpdate(aNum: integer; aSQL: string);
> но могу "забиться" на то что там тот же стиль, с переменными
> сделанными частью запроса...
> вот это вот я и называю идиотским подходом. неважно с чем
> ты там несогласен.

Ага, дошло. Спасибо, буду думать.


>
> > Я не собираюсь изобретать велосипед и переписывать компонент.
>
> поздравляю, хоть и не хотел, но начал.


И в чем это выражается?


> > а так достаточно внести изменения в сервисную функцию.
>
> вот вот. привычка к своему велосипеду уже сказывается. вместо
> того чтобы изыскать методы при нормальной работе.


Что есть "методы при нормальной работе"?
Писать одинаковый код в сотне мест, а затем для внесения изменений перелопачивать весь проект? Чувствую, все-таки я чего-то не понял :)


 
ANB   (2008-05-16 15:40) [22]


> Писать одинаковый код в сотне мест, а затем для внесения
> изменений перелопачивать весь проект? Чувствую, все-таки
> я чего-то не понял :)

Если выносишь какой то код в процедуру/метод, то надо вынести его так, чтобы было правильно. А правильно - работать с параметрами, а не генерить на кажный чих новый запрос.



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

Текущий архив: 2008.12.07;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.013 c
2-1225276621
Andy BitOff (PPC)
2008-10-29 13:37
2008.12.07
Exception


15-1222873439
Городской Шаман
2008-10-01 19:03
2008.12.07
Обработчики исключений SEH vs classic C++


3-1211225835
Ary
2008-05-19 23:37
2008.12.07
Сортировка


15-1223305707
Slider007
2008-10-06 19:08
2008.12.07
С днем рождения ! 5 октября 2008 воскресенье


15-1222946859
Поросенок Винни-Пух
2008-10-02 15:27
2008.12.07
недвижимость в мичигане за пару баксов