
Ved Renden 31 2870 Dyssegaard Tel. +45 23 34 54 43
| 
MainframeSupports tip uge 51/2002:
Lige siden fremkomsten af DB2 har vi kæmpet mod deadlocks og timeouts.
Et væsentligt skridt i den rigtige retning blev taget med indførelsen af
TYPE 2 indexes i version 4. Der er dog stadig mange situationer, hvor der opstår
deadlocks eller timeouts i de applikationer, der benytter DB2. Jeg vil i dette tip komme
med et lille bidrag til nedkæmpelsen af timeouts i forbindelse med INSERT's på
tabeller med unique indexes.
Tippet giver kun mening, hvis to programmer samtidig prøver på at
indsætte en række med samme unikke nøgle på den samme tabel. Det
begrænser selvfølgelig udvalget af situationer, hvor tippet er relevant
væsentligt. Jeg har benyttet det til at fjerne en dødirriterende timeout i en
parallel afvikling af det samme program, hvor det viste sig, at to af de parallelt eksekverende
jobs hele tiden ville indsætte den samme række på den samme tabel.
Det ene job fik lov til at vente, mens det andet job fortsatte så længe uden at
commit'te, at det ventende job til sidst fik en timeout. Normal løsning på den
slags problemer er selvfølgelig at sætte commit-hyppigheden ned, men en skæv
datafordeling og kravene til hastigheden gjorde, at det ikke var nogen god løsning.
Jeg fandt derfor på følgende udvej:
SELECT key_value
INTO :host-key-value
FROM problem_table
WHERE key_value = :host-key-value
WITH UR
;
IF SQLCODE = 100
THEN
INSERT INTO problem_table ...
Jeg lavede simpelthen en SELECT før INSERT'en, der ved hjælp af en "dirty read"
finder ud af, om rækken med den pågældende unikke værdi er til stede i
tabellen. Fidusen er, at WITH UR gør det muligt for DB2 at se endnu ikke commit'tede
ændringer. Derfor kan programmet nu selv kontrollere om det vil havne i en
timeout-situation eller ej. Det gode ved denne løsning er, at programmet slet ikke
kommer til at vente overhovedet, mens det dårlige er, at der skal bruges ekstra
DB2-ressourcer på det ekstra og i princippet overflødige select-kald. Der er
stadig en minimal risiko for at havne i en timeout, hvis det parallelt eksekverende program
får kontrollen og laver sin insert, imens ovenstående programkode udfører
IF'en.
Man kan også komme i den situation, at den programeksekvering, der først laver
insert'en ender med at lave rollback. Så er det selvfølgelig ikke så godt,
at vi lader som om, at rækken rent faktisk findes. Derfor skal man nøje overveje
brugen af dette tip.
I min situation gjalt det om at opsamle nøgle-værdien til et
efterfølgende job, som også var afhængig af, at de parallelt eksekverende
jobs også blev afviklet OK. Hvis den anden programeksekvering lavede rollback, blev den
restartet og ville derfor ved en efterfølgende succesfuld afslutning have opsamlet den
manglede nøgle-værdi.
Forrige danske tip
Last tip in english
Tip oversigten
|