4

私は PostgreSQL 9.3 を使用しており、いくつかのステートメントを含むいくつかのストアド プロシージャを作成しています。プリペアド ステートメントを使用して、Java アプリケーションでこのストアド プロシージャを呼び出しています。

ここで、ストアド プロシージャ内の各ステートメントがトランザクションとして実行されることを読みました。つまり、各ステートメントの後に 1 つのコミットです。しかし、私が望むのは、ストアド プロシージャ全体を 1 つのトランザクション、つまり 1 つのコミットのみとして実行することです。

これどうやってするの?おそらくJDBCレベルで自動コミットを無効にしていますか?

4

1 に答える 1

13

基本的に、ストアド プロシージャ本質的にアトミックであり、1 つのトランザクションとして実行されます。

CREATE TABLE xxx (id int PRIMARY KEY);

CREATE OR REPLACE FUNCTION f() RETURNS void AS $$
DECLARE
  len int;
BEGIN
  RAISE NOTICE 'Transaction ID: %', TXID_CURRENT();
  INSERT INTO xxx VALUES (1);

  RAISE NOTICE 'Transaction ID: %', TXID_CURRENT();
  INSERT INTO xxx VALUES (2);

  RAISE NOTICE 'Transaction ID: %', TXID_CURRENT();
  SELECT COUNT(*) FROM xxx INTO len;
  RAISE NOTICE 'Number of records: %', len;

  RAISE NOTICE 'Transaction ID: %', TXID_CURRENT();

  -- results in unique constraint violation
  UPDATE xxx SET id = 3;
END;
$$ LANGUAGE plpgsql;

f()次に、から呼び出してみてくださいpsql

stackoverflow=# show autocommit;
 autocommit 
------------
 on
(1 row)

stackoverflow=# SELECT f();
NOTICE:  Transaction ID: 15086
NOTICE:  Transaction ID: 15086
NOTICE:  Transaction ID: 15086
NOTICE:  Number of records: 2
NOTICE:  Transaction ID: 15086
ERROR:  duplicate key value violates unique constraint "xxx_pkey"
DETAIL:  Key (id)=(3) already exists.
CONTEXT:  SQL statement "UPDATE xxx SET id = 3"
PL/pgSQL function f() line 20 at SQL statement

stackoverflow=# SELECT * FROM xxx;
id 
----
(0 rows)
于 2014-10-16T14:13:22.137 に答える