설명된 대로 데이터베이스 액세스로 인해 발생한 오류 복구 중섹션 46.7.2일부 작업 중 하나가 실패하기 전에 일부 작업이 성공하고 해당 오류에서 복구한 후 데이터가 일관되지 않은 상태로 남아 있는 바람직하지 않은 상황이 발생할 수 있습니다. PL/Python은 무지개 토토적 하위 트랜잭션의 형태로 이 문제에 대한 솔루션을 제공합니다.
두 계정 간의 이체를 구현하는 기능을 고려해보세요:
함수 만들기 transfer_funds() $$로 무효 반환
시도해 보세요:
plpy.execute("계정 업데이트 SET 잔액 = 잔액 - 100 WHERE account_name = 'joe'")
plpy.execute("계정 업데이트 SET 잔액 = 잔액 + 100 WHERE account_name = 'mary'")
e로 plpy.SPIError를 제외하고:
result = "자금 이체 오류: %s" % e.args
그 외:
결과 = "자금이 올바르게 이체되었습니다"
plan = plpy.prepare("INSERT INTO 작업(결과) VALUES ($1)", ["text"])
plpy.execute(계획, [결과])
$$ 언어 plpythonu;
만약 두 번째업데이트문 결과 예외가 발생합니다. 이 함수는 오류를 보고하지만 첫 번째 결과는업데이트그럼에도 불구하고 커밋됩니다. 즉, Joe의 계좌에서 자금이 인출되지만 Mary의 계좌로 이체되지는 않습니다.
이러한 문제를 방지하려면 다음을 포장할 수 있습니다.plpy.execute무지개 토토적인 하위 트랜잭션을 호출합니다.plpy모듈은 다음으로 생성된 명시적 하위 트랜잭션을 관리하기 위한 도우미 개체를 제공합니다.plpy.subtransaction()함수. 이 함수로 생성된 객체는컨텍스트 관리자 인터페이스. 명시적인 하위 트랜잭션을 사용하여 함수를 다음과 같이 다시 작성할 수 있습니다.
함수 생성 transfer_funds2() $$로 무효 반환
시도해 보세요:
plpy.subtransaction()을 사용하여:
plpy.execute("계정 업데이트 SET 잔액 = 잔액 - 100 WHERE account_name = 'joe'")
plpy.execute("계정 업데이트 SET 잔액 = 잔액 + 100 WHERE account_name = 'mary'")
e로 plpy.SPIError를 제외하고:
result = "자금 이체 오류: %s" % e.args
그 외:
결과 = "자금이 올바르게 이체되었습니다"
plan = plpy.prepare("INSERT INTO 작업(결과) VALUES ($1)", ["text"])
plpy.execute(계획, [결과])
$$ 언어 plpythonu;
다음의 사용에 유의하세요시도해 보세요/제외여전히 필요합니다. 그렇지 않으면 예외가 Python 스택의 맨 위로 전파되어 전체 함수가 a로 중단됩니다.포스트그레SQL오류로 인해작업테이블에는 삽입된 행이 없습니다. 하위 트랜잭션 컨텍스트 관리자는 오류를 포착하지 않고 해당 범위 내에서 실행되는 모든 데이터베이스 작업이 원자적으로 커밋되거나 롤백되도록 보장합니다. 하위 트랜잭션 블록의 롤백은 데이터베이스 액세스에서 발생한 오류뿐만 아니라 모든 종류의 예외 종료 시 발생합니다. 명시적인 하위 트랜잭션 블록 내에서 발생하는 일반 Python 예외로 인해 하위 트랜잭션이 롤백될 수도 있습니다.
다음을 사용하는 컨텍스트 관리자 구문함께키워드는 Python 2.6에서 기본적으로 사용할 수 있습니다. 이전 Python 버전과의 호환성을 위해 하위 트랜잭션 관리자의__enter__그리고__exit__함수를 사용하는입력그리고출구편의 별칭. 자금을 이체하는 예제 함수는 다음과 같이 작성할 수 있습니다.
함수 생성 transfer_funds_old() $$로 무효 반환
시도해 보세요:
subxact = plpy.subtransaction()
subxact.enter()
시도해 보세요:
plpy.execute("계정 업데이트 SET 잔액 = 잔액 - 100 WHERE account_name = 'joe'")
plpy.execute("계정 업데이트 SET 잔액 = 잔액 + 100 WHERE account_name = 'mary'")
제외:
수입 시스템
subxact.exit(*sys.exc_info())
올리다
그 외:
subxact.exit(없음, 없음, 없음)
e로 plpy.SPIError를 제외하고:
result = "자금 이체 오류: %s" % e.args
그 외:
결과 = "자금이 올바르게 이체되었습니다"
plan = plpy.prepare("INSERT INTO 작업(결과) VALUES ($1)", ["text"])
plpy.execute(계획, [결과])
$$ 언어 plpythonu;
문서에 올바르지 않은 내용이 있으면 일치하지 않습니다. 특정 기능에 대한 경험이 있거나 추가 설명이 필요한 경우 이용해주세요이 양식문서 문제를 보고합니다.