Форум: "Базы";
Текущий архив: 2008.12.07;
Скачать: [xml.tar.bz2];
ВнизТранзакции в 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;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.005 c