2011-11-16 32 views
6

Postgresのドキュメントに従って - 準備が整ったら、COMMIT PREPAREDまたはROLLBACK PREPAREDを使用してトランザクションを後でコミットまたはロールバックすることができます。これらのコマンドは、私は、データベーステーブルにcsvファイルからデータをインポートしようとしています。このために、私はこのすべては、シェルスクリプトで行われPREPARE TRANSACTIONの作業方法

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

を使用しています、どのセッションからnot only the one that executed the original transaction.

を発行することができます。 今の問題は、私はpsqlコマンドを実行し、(私はそのコマンドに

prepare transaction 'some-id'コマンドを使用してトランザクションを開始)-cオプションでパラメータとして、このコマンドを渡していますということです。

セーブポイントを作成し、エラーが発生した場合はロールバックする必要があります。シェルスクリプトでいくつかの他のタスクの後

、私は以前psqlの文が生成されていることをエラーをチェックし、ときに私は、コマンド

Prepared Rollback 'transaction-id'(別psql command with sql statements中)

それを使用してロールバックしてみてくださいレポート "No "transaction-id" found"

私はコンセプトが間違っているか、プロセスに何か不足していますか?

psqlコマンドを複数回発行しており、それぞれ新しいトランザクションが発生しているため、これは起こっていますか?

答えて

8

ご準備のため、COPYPREPAREは同じセッションに参加する必要があります。あなたの質問は具体的なコマンドを欠いているので、私はあなたが書くときと仮定しています:

(SQL文で別々にpsqlコマンドで)ロールバック「トランザクションID」を準備

あなたは別の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を実行すると、トランザクションなしで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がゼロである

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

場合、psqlはトランザクションIDが見つからなかったことを報告しますが、この機能が無効であることについて警告を発しません。 PsqlはPREPARE TRANSACTIONの警告を出しますが、prepare文の後にシェルスクリプトが何かを出力するのは間違いです。

PREPARE TRANSACTION
3

は、通常、トランザクション・モニタまたは同様のアプリケーション・サーバー(例えば、EJB)によって使用複数横切る分散トランザクションサーバ、のためのものです。あなたが途中でセーブポイントを使用する場合は、SAVEPOINT some_nameを使用

START TRANSACTION; 
COPY ....; 
COMMIT; 

、その後、あなたはそのセーブポイントにロールバックすることができます

単に通常のトランザクションブロックにコピーを包みます。

関連する問題