繁体   English   中英

如何使PREPARE TRANSACTION工作

[英]How to make PREPARE TRANSACTION work

根据Postgres文档 - 一旦准备好,稍后可以使用COMMIT PREPARED或ROLLBACK PREPARED提交或回滚事务。 这些命令可以从任何会话发出, not only the one that executed the original transaction.会话not only the one that executed the original transaction.

我试图将数据从csv导入数据库表,为此,我正在使用

COPY tablename [ ( column [, ...] ) ] FROM { 'filename' }

所有这些都是在shell脚本中完成的。 现在的问题是我正在执行psql命令并通过-c选项将此命令作为参数传递(我通过命令启动事务

在该命令中prepare transaction 'some-id' )。

我想创建一个Savepoint并回滚到它,包含任何错误。

在shell脚本中执行了一些其他任务之后,我检查以前的psql语句产生的错误,然后我尝试使用命令回滚

Prepared Rollback 'transaction-id' (在psql command with sql statements单独psql command with sql statements

它报告“ No "transaction-id" found

我在这个过程中错误地或错过了某些概念吗?

这是否发生是因为我多次发出psql命令并且每次都导致新的事务?

为了准备工作, COPYPREPARE必须在同一个会话中。 由于你的问题缺乏具体的命令,我假设你写的时候:

Prepared Rollback'transaction-id'(在带有sql语句的单独psql命令中)

您正在使用不同的psql命令来COPY和PREPARE。 这是错的。 将COPY和PREPARE组合到同一会话中。

例如

$ psql -c "BEGIN; COPY tablename FROM '/tmp/sql'; PREPARE TRANSACTION 'foobar';" db
$ while /bin/not-ready-to-commit ; do sleep 1 ; done
$ psql -c "COMMIT PREPARED 'foobar';" db

PREPARE TRANSACTION通过将当前事务写入光盘并退出当前会话中的事务处理来工作。 这就是为什么你需要一个BEGIN :它启动你想要准备的交易。 您希望受prepeare影响的所有命令必须在事务启动后(在您的情况下为COPY命令)。 发出PREPARE TRANSACTION ,您当前所在的事务将使用您提供的标识符写入磁盘。 准备交易后发布的任何声明不再是交易的一部分。 所以做BEGIN; PREPARE... ; COPY BEGIN; PREPARE... ; COPY BEGIN; PREPARE... ; COPY在没有事务的情况下运行COPY操作。

这是psql shell中的一个例子:

demo=# DELETE FROM foo;
DELETE 4
demo=# BEGIN; -- start a transaction
BEGIN
DEMO=# COPY foo FROM '/tmp/sql'; -- do what you want to commit later
COPY 4
demo=# PREPARE TRANSACTION 'demo'; -- prepare the transaction
PREPARE TRANSACTION
demo=# ROLLBACK; -- this is just to show that there is no longer a transaction
NOTICE:  there is no transaction in progress
ROLLBACK
demo=# SELECT * FROM foo; -- the table is empty, copy waiting for commit
 a | b 
---+---
(0 rows)
demo=# COMMIT PREPARED 'demo'; -- do the commit
COMMIT PREPARED
demo=# SELECT * FROM foo; -- data is visible
 a | b 
---+---
 1 | 2
 3 | 4
 5 | 6
 7 | 8
(4 rows)

编辑:您必须在postgresql.conf中启用准备好的事务:

max_prepared_transactions = 1 # or more, zero (default) disables this feature.

如果max_prepared_transactions为零,则psql报告未找到事务标识,但不会警告您禁用此功能。 Psql为PREPARE TRANSACTION提供警告,但是如果你的shell脚本在prepare语句之后打印东西,很容易错过。

PREPARE TRANSACTION用于跨多个服务器的分布式事务,通常由事务监视器或类似的应用程序服务器(例如EJB)使用。

只需将您的副本包装在常规事务块中:

START TRANSACTION;
COPY ....;
COMMIT;

如果要在中间使用保存点,请使用SAVEPOINT some_name ,然后可以回滚到该保存点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM