PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Transação Autônoma no PostgreSQL 9.1

Atualmente estou trabalhando em Migrações de Oracle para PostgreSQL. Apesar de ser DBA, hoje em dia estou aprendendo um pouco na área de Desenvolvedor também… 🙂
Vamos ver um pequeno recurso do Oracle e de forma semelhante no PostgreSQL.

Transação Autônoma, o que é?

Uma transação autônoma é uma transação independente que é iniciada por outra transação e executada sem interferir na transação pai. Quando uma transação autônoma é chamada, a transação de origem é suspensa. O controle é retornado quando a transação autônoma faz um COMMIT ou ROLLBACK.

Exemplo no 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

No meu exemplo acima, a linha 3 fez o commit da linha 2, onde ela tem que ser revertida de acordo com a linha 4. No meu exemplo estou procurando por blocos de transação para se comportar de forma independente, para conseguir isso no Oracle precisamos incluir PRAGMA autônoma_transaction no procedimento declaração para se comportar como bloco de transação independente. Vamos Retomar:
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

Como fazer funcionar no PostgreSQL?

Transações Autônomas, são muito bem controladas no Oracle. Funcionalidade semelhante não existe no PostgreSQL, mas você pode conseguir com um hack usando o dblink. Abaixo está o link, onde o hack foi fornecido:
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)

Não é simples, graças ao provedor de hack.