I'm using PostgreSQL 9.3 and I have some stored procedures created which contains several statements. I'm calling this stored procedures in a Java application with the help of a prepared statement.
Now I've read that each statement inside the stored procedure is executed as a transaction, i.e. one commit after each statement. But what I want is to have the whole stored procedure executed as one transaction, i.e. only one commit.
How can I do this? Perhaps deactivating autocommit on the JDBC level?
Well, basically stored procedures are atomic in nature and executed as one transaction.
CREATE TABLE xxx (id int PRIMARY KEY);
CREATE OR REPLACE FUNCTION f() RETURNS void AS $$
DECLARE
len int;
BEGIN
RAISE NOTICE 'Transaction ID: %', TXID_CURRENT();
INSERT INTO xxx VALUES (1);
RAISE NOTICE 'Transaction ID: %', TXID_CURRENT();
INSERT INTO xxx VALUES (2);
RAISE NOTICE 'Transaction ID: %', TXID_CURRENT();
SELECT COUNT(*) FROM xxx INTO len;
RAISE NOTICE 'Number of records: %', len;
RAISE NOTICE 'Transaction ID: %', TXID_CURRENT();
-- results in unique constraint violation
UPDATE xxx SET id = 3;
END;
$$ LANGUAGE plpgsql;
Then try invoking f()
from psql
.
stackoverflow=# show autocommit;
autocommit
------------
on
(1 row)
stackoverflow=# SELECT f();
NOTICE: Transaction ID: 15086
NOTICE: Transaction ID: 15086
NOTICE: Transaction ID: 15086
NOTICE: Number of records: 2
NOTICE: Transaction ID: 15086
ERROR: duplicate key value violates unique constraint "xxx_pkey"
DETAIL: Key (id)=(3) already exists.
CONTEXT: SQL statement "UPDATE xxx SET id = 3"
PL/pgSQL function f() line 20 at SQL statement
stackoverflow=# SELECT * FROM xxx;
id
----
(0 rows)