Forum OpenACS Q&A: Transactions in PL/PgSQL ?

Collapse
Posted by Roberto Mello on
Is it possible to have transactions in a PL/PgSQL function? If so,
how? I haven't been successful in my attempts and the documentation
does not say.

    TIA.
Collapse
Posted by Dan Wickstrom on
I think that I remember this coming up in the postgresql hackers mailing list.  Try searching the archives.  You might also want to try implementing it as an 'sql' function if possible.
Collapse
Posted by Tom Jackson on

Did anyone ever get transactions to work in plpgsql? I am trying the following, which works fine with out the transaction statements:

begin transaction;

insert into ms_customer_credit_ledger (ledger_id,
 credit_id, type_id, amount, description)
values (nextval(''ms_credit_ledger_seq''),v_credit_row.credit_id,
 4,v_credit_total ,''credit for item '' || 
 NEW.item_id);

update ms_customer_credit 
 set balance = (balance - v_credit_total)
where
 credit_id = v_credit_row.credit_id;

commit;

Alternatively, can I wrap the tcl code in a transaction and have it work?

Collapse
Posted by David Walker on
I thought I read somewhere that each function is automatically a transaction
and that you cannot have nested transactions.  I can't remember where I got
that idea however.
Collapse
Posted by Dan Wickstrom on
Yes that is correct - the top-level function is a transaction, and transactions do not nest.
Collapse
Posted by Don Baccus on
Slight correction ... every top-level PG statement is executed in an implicit transaction if it is not part of an explicit transaction (i.e. not wrapped in BEGIN/END).

Since functions can only be called from within SQL statement in PG, in practice Dan's statement work well enough.  But in some cases, for instance where concurrency impacts tuple visibility, it's important to know that all function calls within a PG statement execute within the explicit or implicit transaction containing the statement.

Collapse
Posted by Tom Jackson on

I think what I am lead to believe by these statements is that, for instance, if I call a function, all the dml gets executed, or rolled back? If a sql statement inserts data into one table, which fires a trigger which inserts data into another table, will the whole thing rollback if the second insert fails? I actually have two levels of triggers in one case, where the second insert fires a second trigger which updates a third table.

Collapse
Posted by Don Baccus on
It's all one transaction so everything rolls back or everything commits.