PostgreSQL 11 – Server-side Procedures (Part 2)
Transaction control in PL procedures
A couple of months back, I wrote about how we now have the ability to write Stored Procedures in PostgreSQL. This post follows up on that and talks about the next step that was implemented: transaction control in PL procedures. The feature was committed on 22-Jan-2018.
With this addition, you now have the ability to call COMMIT and ROLLBACK commands in PL/pgSQL from within a procedure. To illustrate:
CREATE TABLE test1 (a int); CREATE PROCEDURE transaction_test1() AS $ BEGIN FOR i IN 0..9 LOOP INSERT INTO test1 (a) VALUES (i); IF i % 2 = 0 THEN RAISE NOTICE 'i=%, txid=% will be committed', i, txid_current(); COMMIT; ELSE RAISE NOTICE 'i=%, txid=% will be rolledback', i, txid_current(); ROLLBACK; END IF; END LOOP; END $ LANGUAGE PLPGSQL;
The results are as follows:
test=# CALL transaction_test1(); NOTICE: i=0, txid=723 will be committed CONTEXT: PL/pgSQL function transaction_test1() line 6 at RAISE NOTICE: i=1, txid=724 will be rolledback CONTEXT: PL/pgSQL function transaction_test1() line 9 at RAISE NOTICE: i=2, txid=725 will be committed CONTEXT: PL/pgSQL function transaction_test1() line 6 at RAISE NOTICE: i=3, txid=726 will be rolledback CONTEXT: PL/pgSQL function transaction_test1() line 9 at RAISE NOTICE: i=4, txid=727 will be committed CONTEXT: PL/pgSQL function transaction_test1() line 6 at RAISE NOTICE: i=5, txid=728 will be rolledback CONTEXT: PL/pgSQL function transaction_test1() line 9 at RAISE NOTICE: i=6, txid=729 will be committed CONTEXT: PL/pgSQL function transaction_test1() line 6 at RAISE NOTICE: i=7, txid=730 will be rolledback CONTEXT: PL/pgSQL function transaction_test1() line 9 at RAISE NOTICE: i=8, txid=731 will be committed CONTEXT: PL/pgSQL function transaction_test1() line 6 at RAISE NOTICE: i=9, txid=732 will be rolledback CONTEXT: PL/pgSQL function transaction_test1() line 9 at RAISE CALL test=# SELECT xmin,* FROM test1; xmin | a ------+--- 723 | 0 725 | 2 727 | 4 729 | 6 731 | 8 (5 rows)
Why is this important?
Well, a big driver behind getting the initial infrastructure in for PL procedures was to allow the ability to control transactions within the procedure. Functions don’t allow you to do that, they operate within a transaction. With this functionality, you will be able to operate across transactions. This allows you commit control over your transactions based on your business logic and program flow.
Very cool!
There are a few limitations. An example is that you can only use the transaction control features in a procedure called from the top level, and not one called from another procedure or function instance.
The feature implements this transaction control (in varying syntax) in each of the supplied procedural languages: PL/pgSQL, PL/Perl, PL/Python, PL/Tcl.
I’ve been waiting for it for many years!. Any plan for autonomous transactions? Thanks.
You might want to take a look at this: https://wiki.postgresql.org/wiki/Autonomous_subtransactions
Its an amazing feature.
Its a big Feature.
What is with Returning multiple result sets?
Multiple Result Sets are planned for the future. I briefly mentioned them in the first part of this blog here: https://blog.2ndquadrant.com/postgresql-11-server-side-procedures-part-1/
So with the release of postgres 11, it is still not possible to create an ms-sql like stored procedure that returns multiple result sets?
If it is not, is this feature on the roadmap?
Is multiple results set will release in pg12