jeste k ciselnikum se since/until

Radek Kanovsky rk na dat.cz
Pondělí Červenec 28 12:34:53 CEST 2003


On Mon, Jul 28, 2003 at 08:12:37AM +0200, Karel Zak wrote:

>  Nevim proc mne to napadlo az ted, ale toto reseni je napriklad
>  pouzivane v triggerech starajicich se o referencni intefritu (FK) kde
>  se resi naprosto podobny problem. Tedy je treba prekontrolovat
>  tabulku s primarnim klicem a nasledne provest insert/update v tabulce 
>  s FK - zaroven je nutne zajistit, aby PK nebyl odstranen dokud vse
>  nebude commitnute. Je to tedy dostatecne vyzkousene reseni :-) Takze:
> 
>  BEGIN;
>  LOCK ciselnik IN ROW SHARE MODE;
>  SELECT 1 FROM ciselnik WHERE ..kotrola since/until.. FOR UPDATE;
>  INSERT INTO ciselnik ....;
>  COMMIT;
> 
>  Ten INSERT pochopitelne pokud select nic nevrati.
>  
>  Je treba pouzit jak FOR UPDATE tak ROW SHARE MODE, vice viz. docs.

Zdravim a dekuji za spolupraci. Nejak mne to neni jasne. Ten ROW SHARE
lock se mi zda malo restriktivni, protoze ten je podle dokumentace v
konfliktu pouze s prikazy ALTER TABLE, DROP TABLE a VACUUM FULL a s
explicitnim exkluzivnim lockem. Budiz, asi by tam mel byt, ale podle
me nijak neprispiva k reseni problemu. SELECT FOR UPDATE zase jenom
zamkne zaznamy, ktere uz v tabulce jsou. Pokud je tabulka prazdna, ve
dvou paralelnich transakcich SELECT FOR UPDATE nevrati nic a INSERT dvou
naprosto stejnych zaznamu probehne, ikdyz zaznamy budou samozrejme v
konfliktu. Delam nekde chybu?

Tento problem se od referencni integrity lisi v tom, ze u RI kontroluju
existenci neceho co uz v referovane tabulce je a ja to muzu zamknout,
kdezto tady kontroluju neexistenci urciteho zaznamu. Paralelni transakce
navzajem nevidi vkladana a updatovana data a tady vidim ten hlavni
problem. SELECT FOR UPDATE nevrati v jedne transakci nic, ikdyz v druhe
transakci je vlozen zaznam, ktery by podmince vyhovoval. Pokud vkladam
zaznam do tabulky na ktere jsou RI omezeni, nevadi pokud referovany
zaznam v druhe tabulce nevidim, ikdyz ho paralelni transakce prave
vlozila. Neporusi to konzistenci, pouze INSERT skonci na RI chybe.

Nejak mne z toho vychazi, ze se neobejdu bez nejake predem pripravene
pomocne struktry, kterou uvidim stejne ve vsech transakcich a na ktere
budu delat zamykani, ktere zabrani paralelnim konfliktnim INSERTum.
Zatim ale zadny inteligentni napad nemam.

Jeste jsem premyslel nad zaangazovanim drive zminovaneho specialniho
UNIQUE indexu. Pokud bych si definoval novy datovy typ "interval" (jako
dva casove udaje od-do) a na nem definoval operator "=" (pres OPERATOR
CLASS) tak, ze dva intervaly by si byly rovny, pokud by se prekryvaly
aspon v jeden den, mohl bych mozna pouzit UNIQUE index nad polozkami
(jedinecny_sloupec, interval). Nemam to ale uplne promyslene. V tom
dusnu to jde pomalu :-)

RadekK


Další informace o konferenci Databases