PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Transazione autonoma in PostgreSQL 9.1

Attualmente sto lavorando su migrazioni da Oracle a PostgreSQL. Anche se sono DBA, in questi giorni sto imparando un po' anche sulla pista degli sviluppatori... 🙂
Vediamo una piccola funzionalità di Oracle e un modo simile in PostgreSQL.

Transazione autonoma, che cos'è?

Una transazione autonoma è una transazione indipendente che viene avviata da un'altra transazione e viene eseguita senza interferire con la transazione padre. Quando viene chiamata una transazione autonoma, la transazione di origine viene sospesa. Il controllo viene restituito quando la transazione autonoma esegue un COMMIT o un ROLLBACK.

Esempio in Oracle:

Create two tables and one procedure as shown below.

create table table_a(name varchar2(50));
create table table_b(name varchar2(50));

create or replace procedure insert_into_table_a is
begin
insert into table_a values('Am in A');
commit;
end;

Lets test it here.

SQL> begin
2 insert into table_b values('Am in B');
3 insert_into_table_a;
4 rollback;
5 end;
6 /

PL/SQL procedure successfully completed.

SQL> select * from table_a;

Am in A

SQL> select * from table_b;

Am in B

Nel mio esempio sopra, la riga 3 ha impegnato la riga 2, dove deve eseguire il rollback in base alla riga 4. Nel mio esempio sto cercando blocchi di transazione che si comportino in modo indipendente, per ottenerlo in Oracle dobbiamo includere PRAGMA autonomo_transaction nella procedura dichiarazione per comportarsi come un blocco di transazione indipendente. Riprendiamo:

Truncate table table_a;
Truncate Table table_b;

create or replace procedure insert_into_table_a is pragma autonomous_transaction;
begin
insert into table_a values('Am in A');
commit;
end;

SQL> begin
2 insert into table_b values('Am in B');
3 INSERT_INTO_TABLE_A;
4 rollback;
5 end;
6 /

PL/SQL procedure successfully completed.

SQL> select * from table_a;

NAME
----------
Am in A

SQL> select * from table_b;

no rows selected

Come far funzionare in PostgreSQL?

Autonomous Transaction, sono molto ben controllati in Oracle. Funzionalità simili non sono presenti in PostgreSQL, tuttavia puoi ottenerle con un hack usando dblink. Di seguito è riportato il link, dove è stato fornito l'hacking:
http://archives.postgresql.org/pgsql-hackers/2008-01/msg00893.php

create extension dblink;

create or replace function insert_into_table_a() returns void as $$
begin
perform dblink_connect('pragma','dbname=edb');
perform dblink_exec('pragma','insert into table_a values (''Am in A'');');
perform dblink_exec('pragma','commit;');
perform dblink_disconnect('pragma');
end;
$$ language plpgsql;

edb=# begin;
BEGIN
edb=# insert into table_b VALUES ('am in B');
INSERT 0 1
edb=# select insert_into_table_a();
insert_into_table_a
---------------------

(1 row)

edb=# select * from table_a;
name
---------
Am in A
(1 row)

edb=# select * from table_b;
name
---------
am in B
(1 row)

edb=# rollback;
ROLLBACK
edb=# select * from table_a;
name
---------
Am in A
(1 row)

edb=# select * from table_b;
name
------
(0 rows)

Non è semplice, grazie al provider di hack.