[Delphi + FB] Lock conflict podczas UPDATE

0

Cześć,

Piszę program w Turbo Delphi na bazie FireBird. Po wykonaniu UPDATE łącznie z wszystkimi
ibTransaction.StartTransaction,
ibQuery.ExecSQL,
ibQuery.Commit
wszystko wygląda w porzadku, ale wykonując potem inny UPDATE dotyczące tego rekordu dostaję komunikat:
"lock conflict on no wait transaction
deadlock
update conflicts with concurent update"

Nie jestem pewien ale wygląda na to że poprzedni UPDATE mi blokuje ten rekord. Jak należy poprawnie zwolnić ten rekord do ponownej edycji ? A może jest jakas inna przyczyna?

Dzięki z góry za pomoc

0

Jeśli pracujesz na Firebird 2.0, to zorientuj się np. w takiej rzeczy:

Jeśli tabela, którą updateujesz jest zależna od innej(tzn. posiada jakiś klucz obcy), to wtedy przykładowo:

TABELA1

ID: BIGINT

TABELA2

ID: BIGINT
ID_TAB1: INTEGER

spowoduje właśnie taki błąd. Tzn. gdy nie do końca typy są zgodne(BIGINT i INTEGER)

0

Niestety pracuję na FB1.5.3, ale faktycznie miałem rozbiezności w typach INTEGER i SMALINT. Poprawiłem i też nie działa. Ten sam błąd.

Z pewnością, poprzedni Update nie jest poprawnie zakończony i nie zwlania rekordu do edycji.
Jeśli za pomocą tej samej procedury wyedytyję inne rekordy to wszystkie potem są zablokowane i pojawia się ten sam błąd.
Dodam że te niby zablokowane rekordy bez problemu mogę edytować za pomocą tego samego Update-u natomiast bład o którym piszę pojawia się przy próbie Update w innym miejscu programu.
Po zamknieciu aplikacji nastepuje zwolnienie tych rekordów.

Jakiego polecenia powinienem użyć aby poprawić ten błąd?

0
jarek265 napisał(a)

Niestety pracuję na FB1.5.3, ale faktycznie miałem rozbiezności w typach INTEGER i SMALINT. Poprawiłem i też nie działa. Ten sam błąd.

Z pewnością, poprzedni Update nie jest poprawnie zakończony i nie zwlania rekordu do edycji.
Jeśli za pomocą tej samej procedury wyedytyję inne rekordy to wszystkie potem są zablokowane i pojawia się ten sam błąd.
Dodam że te niby zablokowane rekordy bez problemu mogę edytować za pomocą tego samego Update-u natomiast bład o którym piszę pojawia się przy próbie Update w innym miejscu programu.
Po zamknieciu aplikacji nastepuje zwolnienie tych rekordów.

Jakiego polecenia powinienem użyć aby poprawić ten błąd?

A weź wywal StartTransaction

0

A weź wywal StartTransaction

O dziwo bez tego zadziałalo, ale sytuacja jest taka sama.
Wnioskuję, że trzeba jakoś zakończyc tą transakcję ale nie wiem jak.
</quote>

0
jarek265 napisał(a)

A weź wywal StartTransaction

O dziwo bez tego zadziałalo, ale sytuacja jest taka sama.
Wnioskuję, że trzeba jakoś zakończyc tą transakcję ale nie wiem jak.
</quote>

To się powinno robić automatem. Popatrz na właściwości TIBDatabase

Możesz spróbować też dać po prostu polecenie SQL: Commit
Chociaż to moim zdaniem zupełnie bez sensu ;)

0

nie
ibQuery.Commit;
tylko
ibTransaction.Commit;

0

Tak właśnie mam. Sorry za pomyłkę w głównym poście, polecenia wyglądają następująco:

ibTransaction.StartTransaction
ibQuery.ParamByName('id').AsString:=Edit3.Text;
ibQuery.ExecSQL;
ibTransaction.Commit;

Natomiast ibQuery.SQL wygląda: 
UPDATE operacja 
SET zasoby_id =:do_zasobu, 
      stat_id='2',
      kolejnosc = :kolejnosc  
WHERE operacja_id=:id

ale w dalszym ciągu mam ten sam błąd. Wydaje mi się że jestto poprawna składnia wykonania najprostszego Update. Może mam błąd w tym drugim Update, który mam zrobiony za pomocą ibStoredProc:

begin
  if (exists(select operacja_id from operacja where (operacja_id = :operacja_id))) then
    update operacja
    set ...,...,...         
    where (operacja_id = :operacja_id);
  else
  begin
    execute procedure GET_NEW_EAN returning_values ean;
    insert into operacja ( ...,...,...  )
    values (...,...,...   );
  end
end

trochę powycinałem niepotrzebnych linii aby nie zaciemniac kodu.
Generalnie po wykonaniu tego pierwszego Update a nastepnie tego drugiego mam błąd:

"lock conflict on no wait transaction deadlock update conflicts with concurrent update"

Co to może być?

0

OK, znalazłem błąd. Właściwość ibQuery.Transaction miało podpiętą inną tranzakcję niż ta którą wywoływałem (ibTransaction.Commit), w efekcie tranzakcja nie była zamknięta.
Już wszystko działa.

Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1