sql >> Base de Datos >  >> RDS >> PostgreSQL

Transacción Autónoma en PostgreSQL 9.1

Actualmente estoy trabajando en Migraciones de Oracle a PostgreSQL. Aunque soy DBA, en estos días también estoy aprendiendo un poco en la pista de Desarrollador... 🙂
Veamos una pequeña característica de Oracle y una forma similar en PostgreSQL.

Transacción Autónoma,¿qué es?

Una transacción autónoma es una transacción independiente que es iniciada por otra transacción y se ejecuta sin interferir con la transacción principal. Cuando se llama a una transacción autónoma, la transacción de origen se suspende. El control se devuelve cuando la transacción autónoma realiza un COMMIT o ROLLBACK.

Ejemplo en 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

En mi ejemplo anterior, la línea 3 ha comprometido la línea 2, donde tiene que retroceder de acuerdo con la línea 4. En mi ejemplo, estoy buscando bloques de transacciones que se comporten de forma independiente, para lograrlo en Oracle necesitamos incluir PRAGMA Autonomous_transaction en el Procedimiento declaración para comportarse como bloque de transacción independiente. Vamos a 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

¿Cómo hacer que funcione en PostgreSQL?

Transacción Autónoma, están muy bien controlados en Oracle. No existe una funcionalidad similar en PostgreSQL, sin embargo, puede lograrlo con un truco usando dblink. A continuación se muestra el enlace, donde se proporcionó el truco:
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)

¿No es simple, gracias al proveedor de piratería?