Oracleの小さな機能とPostgreSQLの同様の方法を見てみましょう。
自律トランザクション、それは何ですか?
自律型トランザクションは、別のトランザクションによって開始され、親トランザクションに干渉することなく実行される独立したトランザクションです。自律トランザクションが呼び出されると、元のトランザクションは一時停止されます。自律トランザクションがCOMMITまたはROLLBACKを実行すると、制御が返されます。
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
上記の例では、3行目が2行目をコミットしており、4行目に従ってロールバックする必要があります。私の例では、独立して動作するトランザクションブロックを探しています。これを実現するには、OracleでPRAGMAautonomous_transactionをプロシージャに含める必要があります。独立したトランザクションブロックとして動作する宣言。再受験しましょう:
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
PostgreSQLで動作させる方法は?
Autonomous Transactionは、Oracleで非常によく制御されています。同様の機能はPostgreSQLにはありませんが、dblinkを使用してハックすることで実現できます。以下は、ハッキングが提供されているリンクです。
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)
ハックプロバイダーのおかげで、それは簡単ではありませんか。