【问题标题】:Execute postgreSQL stored procedure as one transaction将 postgreSQL 存储过程作为一个事务执行
【发布时间】:2014-12-11 22:06:14
【问题描述】:

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

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

我该怎么做?也许在 JDBC 级别停用自动提交?

【问题讨论】:

  • 禁用自动提交并在开始事务后调用该函数。
  • @a_horse_with_no_name 啊,你的意思是第一个 dbConnection.setAutoCommit(false); (事务块开始)然后我执行准备好的语句,然后执行 dbConnection.commit();。这是正确的吗?我必须关心回滚吗?

标签: postgresql jdbc transactions commit autocommit


【解决方案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;

然后尝试从psql 调用f()

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)

【讨论】:

  • 不仅如此,即使您想在存储过程中COMMIT,您也不能这样做。
猜你喜欢
  • 2012-02-26
  • 2016-05-26
  • 1970-01-01
  • 1970-01-01
  • 2017-07-20
  • 1970-01-01
  • 2011-02-18
  • 1970-01-01
  • 2010-09-15
相关资源
最近更新 更多