Форум: "Базы";
Текущий архив: 2005.11.27;
Скачать: [xml.tar.bz2];
ВнизПроблема с Update blob-поля Найти похожие ветки
← →
iamkate © (2005-10-12 14:10) [0]У меня большая проблема.
Есть таблица, с которой одновременно работают много пользователей. В ней есть blob-поле.
И если я пытаюсь сделать update в то время, когда другие пользователи что-то вставляют в таблицу или тоже
делают update, он зависает на строке Execute. Если же никто не делает insert или update, то все проходит нормально, хоть и долго.
До того, как в таблицу добавили blob-поле все шло хорошо и быстро.
Помогите, пожалуйста, решить проблему. (Blob-поле содержит bmp-картинки).
Спасибо.
Привожу пример своей процедуры:
Procedure
Var
lobTmp : TLOBLocator;
buff : ansistring;
fs:TMemoryStream;
begin
with OracleQuery do
begin
Clear;
DeleteVariables;
DeclareVariable("NAME", otString);
DeclareVariable("FAM", otString);
SQL.Clear;
SQL.Add("BEGIN UPDATE_PERSON (:NAME, :FAM); END; ");
SetVariable("NAME", edit1.Text);
SetVariable("FAM", edit2.Text);
Execute;
end;
with MyOracleQuery do
begin
fs:= TMemoryStream.Create;
image.Picture.Bitmap.SaveToStream(fs);
fs.Seek(0, soFromBeginning);
SetLength(buff, fs.Size);
fs.Read(buff[1], fs.Size);
fs.Free;
lobTmp := TLOBLocator.Create(qryBlob.Session, otblob);
SetVariable("ZAL_SUB", FKeyFieldValue);
try
SetComplexVariable("Photo", lobTmp);
try
Execute;
lobTmp.AsString := Buff;
except
on E:Exception do
MessageDlg(E.Message, mtError, [mbYes], 0);
end;
finally
lobTmp.Free;
end;
OracleSession.Commit;
end;
end.
← →
Sergey13 © (2005-10-12 14:22) [1]Перед редактированием
select * from myTable for update of (myBLOBField) NOWAIT
where id=:id
← →
Johnmen © (2005-10-12 14:25) [2]Так это нормально. Или что ты хочешь ?
А вот это место ОЧЕНЬ странное :)Clear; // Наверное Close ???
DeleteVariables;
DeclareVariable("NAME", otString);
DeclareVariable("FAM", otString);
SQL.Clear;
SQL.Add("BEGIN UPDATE_PERSON (:NAME, :FAM); END; ");
SetVariable("NAME", edit1.Text);
SetVariable("FAM", edit2.Text);
Execute;
сначала чистим параметры.
а зачем, если текст запроса далее чиститься (что приводит неявно к уничтожению всех параметров) ?
← →
Val © (2005-10-12 14:27) [3]еще непонятка с явным подтверждением транзакции, которая явно не стартовала
← →
Seg (2005-10-12 14:35) [4]"BEGIN UPDATE_PERSON (:NAME, :FAM); END;
рекомендую вставить commit
"BEGIN UPDATE_PERSON (:NAME, :FAM); COMMIT; END;
Это завершит предыдующие транзакции и может очень ускорить процесс.
← →
Val © (2005-10-12 14:38) [5]>[4] Seg (12.10.05 14:35)
подозреваю, что автору все нужно выполнять как раз в одной транзакции, а не в разных. заполнять и фио и фото.
← →
ANB © (2005-10-12 14:41) [6]
> Johnmen © (12.10.05 14:25) [2]
- в DOA нужно все чистить явно.
← →
ANB © (2005-10-12 14:44) [7]
> И если я пытаюсь сделать update в то время, когда другие
> пользователи что-то вставляют в таблицу или тоже
> делают update,
Другие пользователи должны делать свои инсерты и апдейты максимально быстро. Иначе придется перепроверить логику программы.
> Seg (12.10.05 14:35) [4]
- скорее всего не ускорит.
← →
Sergey13 © (2005-10-12 14:45) [8]Странные параметры для UPDATE_PERSON. (:NAME, :FAM). Ивановых Иванов мало ли? И почему картинку сюда же не передать?
2[6] ANB © (12.10.05 14:41)
Это не чистка параметров, а их пересоздание.
← →
Seg (2005-10-12 14:47) [9]Ускорит, Ораклу не надо будет держать в памяти все незавершенные транзакции по этой таблице.
Кстати инсерты и апдейты остальных пользователей надо сразу же коммитить.
Других вариантов я не вижу.
← →
Sergey13 © (2005-10-12 14:49) [10]2[9] Seg (12.10.05 14:47)
>Ускорит, Ораклу не надо будет держать в памяти все незавершенные транзакции по этой таблице.
а у него их много? Транзакций то?
← →
Johnmen © (2005-10-12 14:54) [11]>ANB © (12.10.05 14:41) [6]
>- в DOA нужно все чистить явно.
А создавать ?
← →
ANB © (2005-10-12 15:12) [12]
> Johnmen © (12.10.05 14:54) [11]
И создавать тоже. Одна из причин, почему я одаком пользуюсь, хотя доа и надежнее.
← →
ANB © (2005-10-12 15:13) [13]
> Seg (12.10.05 14:47) [9]
- он их и так держать не будет, так как наверняка автокоммит включен.
← →
ANB © (2005-10-12 15:15) [14]Автору : Кстати, обрати внимание на Sergey13 © (12.10.05 14:45) [8]. Обновлять по ФИО - это нонсенс. Срочно заводите айдишники.
← →
Sergey13 © (2005-10-12 15:22) [15]2iamkate © (12.10.05 14:10)
>До того, как в таблицу добавили blob-поле все шло хорошо и быстро.
А запросы не переделывали? Может там так и осталосьselect * from table
← →
Sergey13 © (2005-10-12 15:45) [16]2[12] ANB © (12.10.05 15:12)
> Одна из причин, почему я одаком пользуюсь, хотя доа и надежнее.
А че с Клиппера ушел? Там и переменные не надо декларировать. 8-)
← →
iamkate © (2005-10-12 16:23) [17]У меня во всех селектах делается коммит.
Я вытаскиваю данные из таблички, используя хранимую процедурку.
Например(оракловая процедурка):
create or replace procedure Read_Person
(
cursor in out package_person.person_cur
)
is
begin
open cur for
select id,name,photo
from person;
commit;
end;
Получаются какие-то данные
потом я вытаскиваю это в дельфовый грид, например в dxDbGrid
Потом я используя оракловый query, в примере MyOracleQuery (типа TOracleQuery), и используя TLobLocator хочу обновить эти данные
update-ом, после обновления я снова считываю данные той же процедуркой в тот же грид.
У меня нет никаких ошибок.
Но скорость update-a почему-то нестабильна, а иногда вообще зависает.
В чем может быть причина?
← →
Seg (2005-10-12 16:27) [18]Зачем Коммит при селекте?
Коммит надо делать сразу после апдейта.
← →
ANB © (2005-10-12 16:30) [19]
> Sergey13 © (12.10.05 15:45) [16]
- когда пишу скоростные надежные вещи, не требующие работы с интерфейсом - перехожу на DOA.
← →
iamkate © (2005-10-12 16:31) [20]>Зачем Коммит при селекте?
>Коммит надо делать сразу после апдейта.
Это чтобы транзакция не осталась в памяти
Память очищаю
← →
Sergey13 © (2005-10-12 16:36) [21]2 [20] iamkate © (12.10.05 16:31)
>Это чтобы транзакция не осталась в памяти
Память очищаю
С ИБ раньше работал?
← →
ANB © (2005-10-12 16:37) [22]
> iamkate © (12.10.05 16:23) [17]
Уфф. Изгалятель. Блобик загружается без апдейта. Достаешь блобовое поле, вешаешь на него локатор, в локатор записываешь стрим и все закрываешь. По коду - как то странно.
← →
iamkate © (2005-10-12 16:39) [23]Да нет не приходилось
Я от db сразу в Oracle
← →
Seg (2005-10-12 16:39) [24]В процедуре UPDATE_PERSON коммит есть?
← →
Sergey13 © (2005-10-12 16:41) [25]2[17] iamkate © (12.10.05 16:23)
>select id,name,photo
from person;
У вас не убивают за такое? 8-)
← →
iamkate © (2005-10-12 16:42) [26]>>>>>>- как то странно
а что странного?
вообще то мне почему-то кажется с этим вопросом лучше на оракловый сайт зайти
← →
iamkate © (2005-10-12 16:44) [27]>>>В процедуре UPDATE_PERSON коммит есть?
Нет, там нет
Коммит делается в Делфях
например, OracleSession.Commit;
← →
iamkate © (2005-10-12 16:46) [28]>>>У вас не убивают за такое?
не убивают,
а по сути можешь что-нибудь посоветовать? :-)
← →
Seg (2005-10-12 16:49) [29]Поставь коммит во всех хранимых процедурах, сразу после инсерта или апдейта.
После селекта коммит надо убрать.
И не делать OracleSession.Commit в Дельфи для транзакции, которая не запущена из Дельфи.
← →
atruhin © (2005-10-12 16:51) [30]>>select id,name,photo
Он же на клиента всю таблицу тянет вместе с фотографиями. Как тут тормозов не будет?
← →
Sergey13 © (2005-10-12 16:57) [31]2[28] iamkate © (12.10.05 16:46)
>>>У вас не убивают за такое?
>не убивают,
Зря. 8-)
>а по сути можешь что-нибудь посоветовать? :-)
Выкинь фото из запроса. Доставай его отдельным запросом по требованию юзера как я написал в [1].
2[29] Seg (12.10.05 16:49)
>И не делать OracleSession.Commit в Дельфи для транзакции, которая не запущена из Дельфи.
В Оракле транзакция запускается вместе с сессией (грубо конечно) и просто подтверждается или откатывается. После этого как бы начинается новая транзакция. Откуда она "запущена" - фиолетово. Именно поэтому коммиты ставить в процедуры нерекомендуется, ибо процедура может быть частью "другой", более сложной транзакции.
← →
iamkate © (2005-10-12 16:58) [32]>>>для транзакции, которая не запущена из Дельфи.
Но коммит после селекта мне не мешает
У меня процедурок 30 с коммитом работали и работают в одной базе
и не было никаких проблем с этим.
А commit после update не надо - это принцип работы с TLobLocator
← →
Seg (2005-10-12 17:02) [33]после обновления я снова считываю данные той же процедуркой в тот же грид.
А нельзя ли после обновления не вытаскивать обратно на клиент всю таблицу, а обойтись только обновленной записью?
← →
Seg (2005-10-12 17:04) [34]У меня процедурок 30 с коммитом работали и работают в одной базе
и не было никаких проблем с этим.
И не будет, потому, что транзакции не было.
Это просто лишний оператор, Оракл его пропускает и все.
← →
atruhin © (2005-10-12 17:04) [35]Причем здесь транзакции? Тебе же сказали!!!!
Выкинь фото из запроса. Доставай его отдельным запросом по требованию юзера как я написал в [1].
← →
Val © (2005-10-12 17:09) [36]>[29] Seg (12.10.05 16:49)
Поставь коммит во всех хранимых процедурах, сразу после инсерта или апдейта.
Не советуйте глупостей, пожалуйста. Если у вас несколько изменений/удалений/вставок в процедуре - после каждой поставите?
← →
iamkate © (2005-10-12 17:11) [37]>>Выкинь фото из запроса. Доставай его отдельным запросом по требованию >>юзера
попробую так сделать
завтра утром расскажу
пока
← →
Seg (2005-10-12 17:15) [38]Если у вас несколько изменений/удалений/вставок в процедуре - после каждой поставите?
после удаления ставлю всегда.
После добаления/редактирования по мере необходимости, но по окончании процедуры обязательно.
В данном примере согласен, что дело не в редактировании, а в выборке всей таблицы с фотографиями.
Оптимально сделать следующим образом - список сотрудников вывести на экран без фотографий, а при открытии формы редактирования вытазкивать из базы фото редактируемого сотрудника.
← →
ANB © (2005-10-12 17:24) [39]
> Seg (12.10.05 17:15) [38]
Некошерно комиты в процедуры пихать. Могут быть большие грабли при составных транзакциях.
← →
Val © (2005-10-12 17:27) [40]>Seg (12.10.05 17:15)
представим, есть табличка
accountid amount
1 100
2 200
3 300
задача - запомнить остаток, ликвидировать счет 1 (здесь - простое удаление), остаток перенести на счет 3 (именно в такой последовательности, неважно почему - просто пример).
вопрос: скажите, что произойдет с сотней, если после удаления , подтвержденного коммитом произойдет эксепшн?
Страницы: 1 2 вся ветка
Форум: "Базы";
Текущий архив: 2005.11.27;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.013 c