Для подготовки к работе COPY
и PREPARE
должны находиться в одном сеансе. Поскольку в вашем вопросе отсутствуют конкретные команды, я предполагаю, что когда вы пишете:
Подготовленный откат «идентификатор транзакции» (в отдельной команде psql с инструкциями sql)
Вы используете разные команды psql для КОПИРОВАНИЯ и ПОДГОТОВКИ. Это не верно. Объедините КОПИРОВАТЬ и ПОДГОТОВИТЬ к одному сеансу.
1011 * Е.Г. *
$ 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
: он запускает транзакцию, которую вы хотите подготовить. Все команды, на которые вы хотите повлиять подготовкой, должны поступить после запуска транзакции (в вашем случае это команда COPY). Когда выдается PREPARE TRANSACTION
, транзакция, в которой вы находитесь, записывается на диск с указанным вами идентификатором. Любые заявления, выпущенные после подготовки транзакции, больше не являются частью транзакции. Таким образом, BEGIN; PREPARE... ; COPY
запускает операцию COPY без транзакции.
Вот пример в оболочке psql:
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
, но его легко пропустить, если ваши сценарии оболочки будут печатать материал после оператора prepare.