Does encapsulating a statement in a transaction include the triggers it fires?
The effects of a trigger 'belong' to the statement that triggered it, so everything will be rolled back together (with or without explicit transactions):

&gt; create table a(x int);
&gt; create table b(y int check(y &gt; 0));
&gt; insert into b values(1);
&gt; create function t() returns trigger as $$
  begin
    update b set y = -1;
    return null;
  end;
  $$ language plpgsql;
&gt; create trigger at after insert on a execute procedure t();
&gt; insert into a values(0);
ERROR:  new row for relation "b" violates check constraint "b_y_check"
DETAIL:  Failing row contains (-1).
CONTEXT:  SQL statement "update b set y = -1"
PL/pgSQL function t() line 1 at SQL statement
&gt; select * from a;
 x
---
(0 rows)