Re: is this trigger safe and efective? - locking (caching via triiggers) - Mailing list pgsql-hackers

From Decibel!
Subject Re: is this trigger safe and efective? - locking (caching via triiggers)
Date
Msg-id 20070815151953.GB54135@nasby.net
Whole thread Raw
In response to is this trigger safe and efective? - locking (caching via triiggers)  ("Pavel Stehule" <pavel.stehule@gmail.com>)
List pgsql-hackers
I don't like the locking... take a look at Ex 37-1 at the end of
http://lnk.nu/postgresql.org/fhe.html for a better way (though, the
comment below about going into an infinite loop is a good observantion,
but I think perhaps after some number of fast tries it should start
putting a sleep in the loop, rather than just arbitrarily bombing after
10 tries.

Also, I remember discussion on -performance about this from folks using
it in the real world... the problem they ran into is that doing the
updates in the cache/mview table directly bloated it too much... they
found it was better to just insert changes into an interim table, and
then periodically batch-process that table.

On Wed, Aug 15, 2007 at 08:01:24AM +0200, Pavel Stehule wrote:
> Hello
>
> I write sample about triggers and i have question. is my solution
> correct and exists better solution?
>
> Regards
> Pavel Stehule
>
> DROP SCHEMA safecache CASCADE;
>
> CREATE SCHEMA safecache;
>
> CREATE TABLE safecache.source_tbl(category int, int_value int);
>
> CREATE TABLE safecache.cache(category int, sum_val int);
>
> CREATE OR REPLACE FUNCTION safecache.source_tbl_trg_fce()
> RETURNS trigger AS
> $$
> BEGIN
>   IF TG_OP = 'INSERT' THEN
>     -- row cannot exists in cache -- complication
>     -- I would to finish these transaction without conflict
>     IF NOT EXISTS(SELECT category
>                      FROM safecache.cache
>                     WHERE category = NEW.category) THEN
>       LOCK TABLE safecache.cache IN SHARE ROW EXCLUSIVE MODE;
>       -- I have to repeat test
>       IF NOT EXISTS(SELECT category
>                        FROM safecache.cache
>                       WHERE category = NEW.category) THEN
>         INSERT INTO safecache.cache
>            VALUES(NEW.category, NEW.int_value);
>       END IF;
>     ELSE
>       -- simple
>       UPDATE safecache.cache
>          SET sum_val = sum_val + NEW.int_value
>         WHERE category = NEW.category;
>     END IF;
>   ELSEIF TG_OP = 'UPDATE' THEN
>     -- if category is without change simple
>     IF NEW.category = OLD.category THEN
>       UPDATE safecache.cache
>          SET sum_val = sum_val + (NEW.int_value - OLD.int_value)
>         WHERE category = OLD.category;
>     ELSE
>       -- old category has to exists
>       UPDATE safecache.cache
>          SET sum_val = sum_val - OLD.int_value
>         WHERE category = OLD.category;
>       -- new category is maybe problem
>       IF NOT EXISTS(SELECT category
>                        FROM safecache.cache
>                       WHERE category = NEW.category) THEN
>         LOCK TABLE safecache.cache IN SHARE ROW EXCLUSIVE MODE;
>         -- I have to repeat test
>         IF NOT EXISTS(SELECT category
>                          FROM safecache.cache
>                         WHERE category = NEW.category) THEN
>           INSERT INTO safecache.cache
>              VALUES(NEW.category, NEW.int_value);
>         END IF;
>       ELSE
>         -- simple, new category exists
>         UPDATE safecache.cache
>            SET sum_val = sum_val + OLD.int_value
>           WHERE category = NEW.category;
>       END IF;
>     END IF;
>   ELSE -- DELETE
>     -- value have to exist in cache, simple
>     UPDATE safecache.cache
>        SET sum_val = sum_val - OLD.int_value
>       WHERE category = OLD.category;
>   END IF;
>   RETURN NEW;
> END
> $$ LANGUAGE plpgsql;
>
> CREATE TRIGGER actualise_cache
>    AFTER INSERT OR UPDATE OR DELETE
>    ON safecache.source_tbl
>    FOR EACH ROW EXECUTE PROCEDURE safecache.source_tbl_trg_fce();
>
> ---------------------------(end of broadcast)---------------------------
> TIP 7: You can help support the PostgreSQL project by donating at
>
>                 http://www.postgresql.org/about/donate
>

--
Decibel!, aka Jim Nasby                        decibel@decibel.org
EnterpriseDB      http://enterprisedb.com      512.569.9461 (cell)

pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: tsearch2 in PostgreSQL 8.3?
Next
From: Andrew Dunstan
Date:
Subject: Re: CVS corruption/mistagging?