如何使PREPARE TRANSACTION工作

vka*_*iya 6 sql postgresql transactions

根据Postgres文档 - 一旦准备好,稍后可以使用COMMIT PREPARED或ROLLBACK PREPARED提交或回滚事务.这些命令可以从任何会话发出,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)

它报告" No "transaction-id" found"

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

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

jmz*_*jmz 8

为了您的准备工作,COPY并且PREPARE必须在同一个会话.由于你的问题缺乏具体的命令,我假设你写的时候:

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

PREPARE TRANSACTION写当前事务刻录到光盘,在当前会话中退出交易过程中的作品.这就是为什么你需要BEGIN:它启动你想要准备的交易.您希望受prepeare影响的所有命令必须在事务启动后(在您的情况下为COPY命令).当PREPARE TRANSACTION发出后,您目前在交易中被写入与你给的标识符磁盘.准备交易后发布的任何声明不再是交易的一部分.因此,在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)
Run Code Online (Sandbox Code Playgroud)

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

max_prepared_transactions = 1 # or more, zero (default) disables this feature.
Run Code Online (Sandbox Code Playgroud)

如果max_prepared_transactions为零,则psql报告未找到事务标识,但不会警告您禁用此功能.Psql给出了一个警告,PREPARE TRANSACTION但如果你的shell脚本在prepare语句之后打印出来,很容易错过.


a_h*_*ame 5

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

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

START TRANSACTION;
COPY ....;
COMMIT;
Run Code Online (Sandbox Code Playgroud)

如果你想在中间有一个保存点,使用SAVEPOINT some_name然后你可以回滚到那个保存点。