Re: Triggers on transaction?

From: Benedikt Grundmann <bgrundmann(at)janestreet(dot)com>
To: depesz(at)depesz(dot)com
Cc: Jordan Gigov <coladict(at)gmail(dot)com>, Marko Tiikkaja <marko(at)joh(dot)to>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Triggers on transaction?
Date: 2015-05-27 11:15:19
Message-ID: CADbMkNNagpOQ6fLHcABt4j9xG0u6-4GL2zrqVntspvZGGMKZkA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Wed, May 27, 2015 at 12:07 PM, hubert depesz lubaczewski <
depesz(at)depesz(dot)com> wrote:

> On Wed, May 27, 2015 at 01:55:24PM +0300, Jordan Gigov wrote:
> > Updating a materialized view in my case. It should only update when 2-3
> of
> > our 30+ tables get new data, which for those is kind of rare. Not having
> > such a trigger means I will have to call it in each usage in the code and
> > hope future maintainers don't forget it. This is why I postponed
> migrating
> > the one search query where materialized views would be useful, because
> it's
> > heavy.
>
> Add daemon which runs "LISTEN", and triggers on the underlying tables
> that do NOTIFY.
> When daemon picks something from LISTEN (which happens only after
> commit) - it can do anything that needs to be done, and it will not
> block the transaction, which is an added benefit.
>
> depesz
>
>
You can also emulate once per transaction on commit triggers by a
combination of an
after trigger and a temporary table.

-- Deferred constraint triggers run when the transaction are commited

-- BUT they can only be declared AFTER ROW ! And having many of them

-- can be quiet expensive.

-- Normal triggers are pretty cheap but cannot be deferred

-- So we indirect via an additional table so that per one transaction

-- we issue only one run of the trigger

create unlogged table schedule_work_at_end_of_transaction(b bool);

create function work_at_end_of_transaction() returns trigger language
plpgsql as $$
begin

delete from schedule_work_at_end_of_transaction;

raise notice 'trigger!';

return NEW;

end ;

$$ ;

create constraint trigger work_at_end_of_transaction after insert

on schedule_work_at_end_of_transaction

initially deferred for each row

execute procedure work_at_end_of_transaction();

create table test(t text);

create function schedule_if_necessary() returns trigger language plpgsql as
$$
begin

if not exists (select null from schedule_work_at_end_of_transaction limit
1) then
insert into schedule_work_at_end_of_transaction values(true);

end if;

return NEW;

end;

$$ ;

begin;

do $$

begin

for i in 1..1000 loop

insert into test select s :: text from generate_series(1, 1000) s;

end loop;

end ;

$$ ;

commit;

truncate test;

create trigger schedule_if_necessary after insert or update on test

for each statement

execute procedure schedule_if_necessary();

begin;

do $$

begin

for i in 1..1000 loop

insert into test select s :: text from generate_series(1, 1000) s;

end loop;

end ;

$$ ;

commit;

drop table test;

drop table schedule_work_at_end_of_transaction;

drop function schedule_if_necessary();

drop function work_at_end_of_transaction();

>

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Simon Riggs 2015-05-27 11:36:32 Re: Triggers on transaction?
Previous Message hubert depesz lubaczewski 2015-05-27 11:07:17 Re: Triggers on transaction?