Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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.017 c
14-1131301117
ArtemESC
2005-11-06 21:18
2005.11.27
Лучший Хостинг ...


14-1131457826
Nic
2005-11-08 16:50
2005.11.27
Администрирование класса


4-1127835237
Grief
2005-09-27 19:33
2005.11.27
ошибка с GetDIBits при глубине цвета менее 9 бит.


14-1130847271
Курдль
2005-11-01 15:14
2005.11.27
Про бухгалтерский учет и его принципы.


4-1127290638
umbra
2005-09-21 12:17
2005.11.27
как узнать открыт файл или нет?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский