![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с Update blob-поля
iamkate © (2005-10-12 14:10:00)У меня большая проблема.
Есть таблица, с которой одновременно работают много пользователей. В ней есть 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.
iamkate (2005-10-12 16:31:00) [41]>Зачем Коммит при селекте?
>Коммит надо делать сразу после апдейта.
Это чтобы транзакция не осталась в памяти
Память очищаю
ANB (2005-10-12 16:30:00) [42]
> Sergey13 © (12.10.05 15:45) [16]
- когда пишу скоростные надежные вещи, не требующие работы с интерфейсом - перехожу на DOA.
Seg (2005-10-12 16:27:00) [43]Зачем Коммит при селекте?
Коммит надо делать сразу после апдейта.
iamkate (2005-10-12 16:23:00) [44]У меня во всех селектах делается коммит.
Я вытаскиваю данные из таблички, используя хранимую процедурку.
Например(оракловая процедурка):
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 почему-то нестабильна, а иногда вообще зависает.
В чем может быть причина?
Sergey13 (2005-10-12 15:45:00) [45]2[12] ANB © (12.10.05 15:12)
> Одна из причин, почему я одаком пользуюсь, хотя доа и надежнее.
А че с Клиппера ушел? Там и переменные не надо декларировать. 8-)
Sergey13 (2005-10-12 15:22:00) [46]2iamkate © (12.10.05 14:10)
>До того, как в таблицу добавили blob-поле все шло хорошо и быстро.
А запросы не переделывали? Может там так и осталось
select * from table
ANB (2005-10-12 15:15:00) [47]Автору : Кстати, обрати внимание на Sergey13 © (12.10.05 14:45) [8]. Обновлять по ФИО - это нонсенс. Срочно заводите айдишники.
ANB (2005-10-12 15:13:00) [48]
> Seg (12.10.05 14:47) [9]
- он их и так держать не будет, так как наверняка автокоммит включен.
ANB (2005-10-12 15:12:00) [49]
> Johnmen © (12.10.05 14:54) [11]
И создавать тоже. Одна из причин, почему я одаком пользуюсь, хотя доа и надежнее.
Johnmen (2005-10-12 14:54:00) [50]>ANB © (12.10.05 14:41) [6]
>- в DOA нужно все чистить явно.
А создавать ?
Sergey13 (2005-10-12 14:49:00) [51]2[9] Seg (12.10.05 14:47)
>Ускорит, Ораклу не надо будет держать в памяти все незавершенные транзакции по этой таблице.
а у него их много? Транзакций то?
Seg (2005-10-12 14:47:00) [52]Ускорит, Ораклу не надо будет держать в памяти все незавершенные транзакции по этой таблице.
Кстати инсерты и апдейты остальных пользователей надо сразу же коммитить.
Других вариантов я не вижу.
Sergey13 (2005-10-12 14:45:00) [53]Странные параметры для UPDATE_PERSON. (:NAME, :FAM). Ивановых Иванов мало ли? И почему картинку сюда же не передать?
2[6] ANB © (12.10.05 14:41)
Это не чистка параметров, а их пересоздание.
ANB (2005-10-12 14:44:00) [54]
> И если я пытаюсь сделать update в то время, когда другие
> пользователи что-то вставляют в таблицу или тоже
> делают update,
Другие пользователи должны делать свои инсерты и апдейты максимально быстро. Иначе придется перепроверить логику программы.
> Seg (12.10.05 14:35) [4]
- скорее всего не ускорит.
ANB (2005-10-12 14:41:00) [55]
> Johnmen © (12.10.05 14:25) [2]
- в DOA нужно все чистить явно.
Val (2005-10-12 14:38:00) [56]>[4] Seg (12.10.05 14:35)
подозреваю, что автору все нужно выполнять как раз в одной транзакции, а не в разных. заполнять и фио и фото.
Seg (2005-10-12 14:35:00) [57]'BEGIN UPDATE_PERSON (:NAME, :FAM); END;
рекомендую вставить commit
'BEGIN UPDATE_PERSON (:NAME, :FAM); COMMIT;END;
Это завершит предыдующие транзакции и может очень ускорить процесс.
Val (2005-10-12 14:27:00) [58]еще непонятка с явным подтверждением транзакции, которая явно не стартовала
Johnmen (2005-10-12 14:25:00) [59]Так это нормально. Или что ты хочешь ?
А вот это место ОЧЕНЬ странное :)
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;
сначала чистим параметры.
а зачем, если текст запроса далее чиститься (что приводит неявно к уничтожению всех параметров) ?
Sergey13 (2005-10-12 14:22:00) [60]Перед редактированием
select * from myTable for update of (myBLOBField) NOWAIT
where id=:id