2016-07-25 5 views
1

SQL 쿼리를 실행하려면 pg-promise을 사용하고 있습니다. 쿼리 자체는 외부 .sql 파일에 저장됩니다.Postgresql 캐칭 트랜잭션 오류 및 롤백

트랜잭션을 실행할 때 (예상대로) 오류가 발생하면 Postgres는 트랜잭션을 중단합니다. 내가 실행중인 문제는 트랜잭션이 중단 된 후에 실행하려고하는 별도의 쿼리가 실행되지 않고 대신이 메시지가 나타납니다. "현재 트랜잭션이 중단되고 트랜잭션 블록이 끝날 때까지 명령이 무시됩니다". 쿼리가 psql 콘솔에서 실행되는 경우, 실패한 쿼리 후에 ROLLBACK을 실행하여이 문제를 해결할 수 있습니다. 내 응용 프로그램에서 사용하는 SQL이 외부 파일에 있기 때문에이 옵션을 여기서는 선택하지 않는 것으로 생각합니다. 또한 뭔가 실패 할 경우 전체 트랜잭션을 버려야하기 때문에 Savepoint가 옵션이라고 생각하지 않습니다.

이 오류가 발생하면 어떻게 SQL 파일을 롤백합니까?

여기 참조를 위해 SQL의 :

BEGIN; 

DELETE 
FROM tournament_tossup_values 
WHERE tournament_id = $1 AND 
NOT EXISTS 
(
    SELECT id 
    FROM tournament_match 
    WHERE tournament_id = $1 
); 

UPDATE tournament 
SET bonus_point_value = $5, parts_per_bonus = $6 
WHERE id = $1 AND NOT EXISTS (
    SELECT id 
    FROM tournament_match 
    WHERE tournament_id = $1 
) 
RETURNING bonus_point_value, parts_per_bonus; <-- Any subsequent accesses to the database by the application fail if this transaction fails 

COMMIT; <-- I want to rollback everything if this fails 

사전에 감사합니다!

+0

당신은 라이브러리를 참조하고 있습니다 : 트랜잭션 내부에 두 개의 쿼리로 실행 한 후 DELETE 작업을 하나하고 UPDATE 동작 하나, 그리고 -이를 위해

는 두 개의 파일로 SQL 파일을 분할 [pg-promise] (https://github.com/vitaly-t/pg-promise), 트랜잭션에 대한 지원을 사용하고 있지 않습니다 - 메소드'tx'? 이 경우 우리가하고있는 일의 완전한 코드를 보여주지 않으므로 어떤 일이 일어나고 있는지 확신 할 수 없습니다. 아마도'tx' 메쏘드를 사용하는 것이 가장 좋을 것이며, 모든 예제에서 보여지는 것처럼 질의를 실행할 것입니다. [거래] (https://github.com/vitaly-t/pg-promise#transactions)를 참조하십시오. SQL에 적절한 'ROLLBACK'논리를 제공하지 않으므로 코드를 더 예측 가능하게 만듭니다. –

답변

1

외부 SQL 파일에서 트랜잭션을 구현할 때 COMMITROLLBACK에 대한 모든 적절한 처리를 제공해야합니다. 그렇게하지 않으면 서버 측 코드에서 트랜잭션 상태가 예측할 수 없게되어 결과적으로 오류 유형이 생길 수 있습니다.

이것은 약간 까다로울 수 있으며, 수행하기가 쉽지 않습니다. 이것이 최선의 해결책이 전혀 그것을하지 않는 이유입니다.

Module pg-promise 이미 사용중인 모듈 tx을 통해 신뢰할 수있는 트랜잭션 처리를 제공합니다.

db.tx(t => { 
    return t.batch([ 
     t.none('DELETE...'), 
     t.any('UPDATE...') 
    ]); 
}) 
    .then(data => { 
     // success; 
    }) 
    .catch(error => { 
     // error; 
    }); 
+0

아, 그 해결책은 제가 접근하고있는 것입니다. 한 가지 SQL 파일에 모든 것을 보관할 수있는 솔루션이 없는지 확인하고 싶었습니다. 위에서 설명한 방법대로 구현해 보겠습니다. 감사! :) – mbhuiyan

+0

@mbhuiyan 단일 파일 솔루션이있을 수 있지만, 구현하기가 더 어색 할 것이고,'pg-promise' 트랜잭션이 훨씬 더 사용하기 쉽다면 정말 가치있는 일은 아닙니다. –