2011-11-16 2 views
6

Postgres 문서에 따라 - 일단 준비되면 COMMIT PREPARED 또는 ROLLBACK PREPARED를 사용하여 나중에 트랜잭션을 커밋하거나 롤백 할 수 있습니다. 그 명령은 not only the one that executed the original transaction.PREPARE TRANSACTION 작업을 수행하는 방법

내가 데이터베이스 테이블에 CSV 데이터를 가져올이를 위해, 내가 사용하고 노력하고, 모든 세션에서 발행 할 수 COPY tablename [ (column [, ...]) ] FROM { 'filename' }

이 모든이 쉘 스크립트에서 수행하는

. 이제 문제는 내가 psql 명령을 실행하고 -c 옵션을 통해 매개 변수로이 명령을 전달하고 있다는 점이다 (I 명령이 명령에

prepare transaction 'some-id'를 통해 트랜잭션을 시작).

오류가 발생하면 저장 점을 만들고 롤백하려고합니다. 쉘 스크립트에서 몇 가지 다른 작업 후

, 나는 이전 psql의 문이 생산하는 것이 오류를 확인하고 때 다음 명령

Prepared Rollback 'transaction-id' (별도의 psql command with sql statements에서)

그것을 사용하여 롤백하려고 보고서 "No "transaction-id" found"

나는 개념이 잘못되었거나 그 과정에서 무언가를 놓치고 있습니까?

psql 명령을 여러 번 발행하여 각각 새로운 트랜잭션이 발생하기 때문에 이런 일이 발생합니까?

답변

8

작동 준비를하려면 COPYPREPARE이 동일한 세션에 있어야합니다. 귀하의 질문에 구체적인 명령이 부족하기 때문에, 나는 믿고있어 당신은 쓸 때 :

준비

(별도의 psql의의 SQL 문에 명령) 롤백 '트랜잭션 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 

디스크에 현재의 트랜잭션 (transaction)를 작성하고 현재 세션에서 트랜잭션 프로세스를 종료에 의한 PREPARE TRANSACTION 작품. 따라서 BEGIN이 필요합니다 : 준비하려는 트랜잭션이 시작됩니다. prepeare의 영향을 받으려는 모든 명령은 트랜잭션이 시작된 후에 가져와야합니다 (경우에 따라 COPY 명령). PREPARE TRANSACTION이 발행되면 현재있는 트랜잭션이 사용자가 지정한 식별자로 디스크에 기록됩니다. 트랜잭션 준비가 완료된 후에 발급 된 명령문은 더 이상 트랜잭션의 일부가 아닙니다. 따라서 BEGIN; PREPARE... ; COPY을 수행하면 트랜잭션없이 COPY 작업이 실행됩니다.

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) 

편집 :

여기 psql의 쉘의 예입니다 당신은 PostgreSQL을에 준비된 트랜잭션을 사용하도록 설정해야합니다.conf의는 : max_prepared_transactions가 제로

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

경우, psql의 트랜잭션 ID가 발견되지 않는 것으로보고 있지만,이 기능이 비활성화 것에 대해 경고를하지 않습니다. Psql은 PREPARE TRANSACTION에 대한 경고를 표시하지만 쉘 스크립트가 prepare 문 다음에 내용을 인쇄하면 놓치기 쉽습니다.

3

PREPARE TRANSACTION에 대한 여러 걸쳐 일반적으로 트랜잭션 모니터 또는 이와 유사한 애플리케이션 서버 (예를 들어, EJB)에 의해 사용 서버를 분산 트랜잭션을합니다. 당신이 중간에 세이브 포인트를 원하는 경우, SAVEPOINT some_name을 사용

START TRANSACTION; 
COPY ....; 
COMMIT; 

그리고 당신은 그 저장 점으로 롤백 할 수 있습니다

단순히 일반 트랜잭션 블록의 복사본을 포장.

관련 문제