[英]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
命令并且每次都导致新的事务?
为了准备工作, 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
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.