将postgreSQL存储过程作为一个事务执行

mac*_*ery 4 postgresql transactions commit jdbc autocommit

我正在使用PostgreSQL 9.3,我创建了一些包含多个语句的存储过程.我在准备好的语句的帮助下在Java应用程序中调用此存储过程.

现在我已经读过存储过程中的每个语句都作为事务执行,即在每个语句之后执行一次.但我想要的是将整个存储过程作为一个事务执行,即只有一个提交.

我怎样才能做到这一点?也许在JDBC级别上停用自动提交?

Kou*_*rev 13

好吧,基本上存储过程本质上原子的并且作为一个事务执行.

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;
Run Code Online (Sandbox Code Playgroud)

然后尝试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)
Run Code Online (Sandbox Code Playgroud)

  • 不仅如此,即使您愿意,也无法在存储过程中"执行". (2认同)