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.


Val   (2005-10-12 17:27:00) [21]

>Seg   (12.10.05 17:15)
представим, есть табличка
accountid amount
1 100
2 200
3 300

задача - запомнить остаток, ликвидировать счет 1 (здесь - простое удаление), остаток перенести на счет 3 (именно в такой последовательности, неважно почему - просто пример).
вопрос: скажите, что произойдет с сотней, если после удаления , подтвержденного коммитом произойдет эксепшн?


ANB   (2005-10-12 17:24:00) [22]


> Seg   (12.10.05 17:15) [38]

Некошерно комиты в процедуры пихать. Могут быть большие грабли при составных транзакциях.


Seg   (2005-10-12 17:15:00) [23]

Если у вас несколько изменений/удалений/вставок в процедуре - после каждой поставите?

после удаления ставлю всегда.
После добаления/редактирования по мере необходимости, но по окончании процедуры обязательно.

В данном примере согласен, что дело не в редактировании, а в выборке всей таблицы с фотографиями.

Оптимально сделать следующим образом - список сотрудников вывести на экран без фотографий, а при открытии формы редактирования вытазкивать из базы фото редактируемого сотрудника.


iamkate   (2005-10-12 17:11:00) [24]

>>Выкинь фото из запроса. Доставай его отдельным запросом по требованию >>юзера

попробую так сделать
завтра утром расскажу
пока


Val   (2005-10-12 17:09:00) [25]

>[29] Seg   (12.10.05 16:49)
Поставь коммит во всех хранимых процедурах, сразу после инсерта или апдейта.
Не советуйте глупостей, пожалуйста. Если у вас несколько изменений/удалений/вставок в процедуре - после каждой поставите?


atruhin   (2005-10-12 17:04:00) [26]

Причем здесь транзакции? Тебе же сказали!!!!
Выкинь фото из запроса. Доставай его отдельным запросом по требованию юзера как я написал в [1].


Seg   (2005-10-12 17:04:00) [27]

У меня процедурок 30 с коммитом работали и работают в одной базе
и не было никаких проблем с этим.


И не будет, потому, что транзакции не было.
Это просто лишний оператор, Оракл его пропускает и все.


Seg   (2005-10-12 17:02:00) [28]

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


А нельзя ли после обновления не вытаскивать обратно на клиент всю таблицу, а обойтись только обновленной записью?


iamkate   (2005-10-12 16:58:00) [29]

>>>для транзакции, которая не запущена из Дельфи.

Но коммит после селекта мне не мешает
У меня процедурок 30 с коммитом работали и работают в одной базе
и не было никаких проблем с этим.
А commit после  update не надо - это принцип работы с TLobLocator


Sergey13   (2005-10-12 16:57:00) [30]

2[28] iamkate ©   (12.10.05 16:46)
>>>У вас не убивают за такое?
>не убивают,
Зря. 8-)

>а по сути можешь что-нибудь посоветовать? :-)
Выкинь фото из запроса. Доставай его отдельным запросом по требованию юзера как я написал в [1].

2[29] Seg   (12.10.05 16:49)
>И не делать OracleSession.Commit в Дельфи для транзакции, которая не запущена из Дельфи.

В Оракле транзакция запускается вместе с сессией (грубо конечно) и просто подтверждается или откатывается. После этого как бы начинается новая транзакция. Откуда она "запущена" - фиолетово. Именно поэтому коммиты ставить в процедуры нерекомендуется, ибо процедура может быть частью "другой", более сложной транзакции.


atruhin   (2005-10-12 16:51:00) [31]

>>select id,name,photo
Он же на клиента всю таблицу тянет вместе с фотографиями. Как тут тормозов не будет?


Seg   (2005-10-12 16:49:00) [32]

Поставь коммит во всех хранимых процедурах, сразу после инсерта или апдейта.
После селекта коммит надо убрать.
И не делать OracleSession.Commit в Дельфи для транзакции, которая не запущена из Дельфи.


iamkate   (2005-10-12 16:46:00) [33]

>>>У вас не убивают за такое?
не убивают,
а по сути можешь что-нибудь посоветовать? :-)


iamkate   (2005-10-12 16:44:00) [34]

>>>В процедуре UPDATE_PERSON  коммит есть?

Нет, там нет
Коммит делается в Делфях

например, OracleSession.Commit;


iamkate   (2005-10-12 16:42:00) [35]

>>>>>>- как то странно
а что странного?
вообще то мне почему-то кажется с этим вопросом лучше на оракловый сайт зайти


Sergey13   (2005-10-12 16:41:00) [36]

2[17] iamkate ©   (12.10.05 16:23)
> select id,name, photo
from person;

У вас не убивают за такое? 8-)


Seg   (2005-10-12 16:39:00) [37]

В процедуре UPDATE_PERSON  коммит есть?


iamkate   (2005-10-12 16:39:00) [38]

Да нет не приходилось
Я от db сразу в Oracle


ANB   (2005-10-12 16:37:00) [39]


> iamkate ©   (12.10.05 16:23) [17]

Уфф. Изгалятель. Блобик загружается без апдейта. Достаешь блобовое поле, вешаешь на него локатор, в локатор записываешь стрим и все закрываешь. По коду - как то странно.


Sergey13   (2005-10-12 16:36:00) [40]

2 [20] iamkate ©   (12.10.05 16:31)
>Это чтобы транзакция не осталась в памяти
Память очищаю
С ИБ раньше работал?


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

Наверх

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