Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблема с Update blob-поля


Страницы:   1 2 3

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


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо