Как заставить ПОДГОТОВИТЬ СДЕЛКУ работать - PullRequest
6 голосов
/ 16 ноября 2011

Согласно документации Postgres. После подготовки транзакция может быть зафиксирована или откатана с помощью COMMIT PREPARED или ROLLBACK PREPARED, соответственно.Эти команды могут быть выполнены из любого сеанса, not only the one that executed the original transaction.

Я пытаюсь импортировать данные из csv в таблицы базы данных, и для этого я использую

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

все это делается в скрипте оболочки.Теперь проблема в том, что я выполняю команду psql и передаю эту команду в качестве параметра с помощью опции -c (я запускаю транзакцию с помощью команды

prepare transaction 'some-id' в этой команде).

Я хочу создать точку сохранения и выполнить откат к ней в случае каких-либо ошибок.

После нескольких других задач в сценарии оболочки я проверяю ошибки, которые возникли в предыдущем операторе psql, и когдаЗатем я пытаюсь выполнить откат, используя команду

Prepared Rollback 'transaction-id' (в отдельном psql command with sql statements)

Она сообщает "No "transaction-id" found"

Я неправильно понял концепцию иличто-то отсутствует в процессе?

Это происходит из-за того, что я запускаю команду psql несколько раз, и каждая приводит к новой транзакции?

Ответы [ 2 ]

8 голосов
/ 16 ноября 2011

Для подготовки к работе 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.

3 голосов
/ 16 ноября 2011

PREPARE TRANSACTION предназначен для распределенных транзакций на нескольких серверах, обычно используемых мониторами транзакций или аналогичными серверами приложений (например, EJB).

Просто оберните свою копию в обычный блок транзакции:

START TRANSACTION;
COPY ....;
COMMIT;

Если вы хотите, чтобы точка сохранения находилась посередине, используйте SAVEPOINT some_name, а затем вы можете вернуться к этой точке сохранения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...