프로그래밍SQL 개발자

신뢰할 수 있는 예외 처리 및 SQL 저장 프로시저에서 트랜잭션 롤백을 어떻게 구현하며, 특히 중첩 트랜잭션 시나리오에서 어떻게 해야 합니까? 이러한 솔루션의 제한 사항과 특성은 무엇입니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

역사적으로 SQL에서 오류 처리는 치명적인 오류 발생 후 트랜잭션 롤백으로만 제한되었습니다. 그러나 비즈니스 로직의 발전으로 인해 오류를 정확하게 기록하고, 수행된 변경 사항만 롤백하며, 프로시저 호출의 중첩 가능성이 점점 더 많이 요구되고 있습니다.

문제는 모든 DBMS에서 중첩 트랜잭션이 완전히 지원되지 않는다는 것입니다 (예: MS SQL Server에서는 이것이 실제 트랜잭션이 아니라 저장점(SAVEPOINT)의 수준에 가깝습니다) 그리고 오류 발생 시 예외가 필요한 정리를 방해할 수 있습니다. TRY/CATCH 또는 유사한 메커니즘을 사용하지 않으면 이러한 일이 발생할 수 있습니다.

해결책: TRY/CATCH (또는 유사한 구조) 및 중첩을 위한 SAVEPOINT를 사용하고, 오류 발생 시 프로시저의 동작을 설정합니다 (예: SQL Server에서 SET XACT_ABORT).

코드 예제 (MS SQL Server):

BEGIN TRY BEGIN TRANSACTION -- 작업 EXEC dbo.InnerProcedure COMMIT TRANSACTION END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION -- 오류 기록 INSERT INTO error_log VALUES (ERROR_NUMBER(), ERROR_MESSAGE(), GETDATE()) END CATCH

주요 특징:

  • 오류 포착을 위한 TRY/CATCH 사용.
  • 중첩을 위한 @@TRANCOUNT 제어.
  • 지점(SAVEPOINT)이나 수동으로 복귀점을 제어하기 위한 자체적인 유사 기능.

트릭 질문.

중첩 트랜잭션에서 오류가 발생하면 실제로 모든 변경 사항이 롤백됩니까?

대부분의 DBMS에서 중첩 트랜잭션은 개별 트랜잭션이 아니라 복귀 지점(SAVEPOINT)입니다. 전체 롤백이 수행될 때 초기(바깥) 트랜잭션까지 모든 변경 사항이 롤백됩니다.

@@TRANCOUNT를 확인하지 않고 활성 트랜잭션 외부에서 ROLLBACK을 수행하면 어떻게 됩니까?

오류가 발생합니다 — 롤백할 활성 트랜잭션이 없습니다. 항상 ROLLBACK 전에 @@TRANCOUNT > 0을 확인하십시오.

TRY/CATCH에서 트리거와 커서가 작동합니까?

예, 하지만 트리거의 오류는 CATCH로의 전환을 유발하고 전체 트랜잭션을 롤백할 수 있습니다. 프로시저 본체와 호출되는 객체(프로시저, 트리거) 모두에서 오류 처리를 고려해야 합니다.

일반적인 오류 및 안티 패턴

  • @@TRANCOUNT 확인 부족 — 비활성 트랜잭션 롤백 시도.
  • 중첩 레벨에서 불필요한 COMMIT 또는 ROLLBACK.
  • 모든 세부 정보를 저장하지 않고 오류 기록.

실생활 예제

부정적 케이스

여러 개의 중첩된 프로시저가 있고, 각 프로시저가 TRY/CATCH 없이 BEGIN TRANSACTION / COMMIT을 사용하여 오류 발생 시 일부 데이터가 변경되고 일부는 그렇지 않은 경우.

장점:

  • 간단한 코드

단점:

  • 상태 불일치
  • 실패 후 모호한 오류

긍정적 케이스

모든 로직이 TRY/CATCH로 감싸져 있고, 중첩된 프로시저가 SAVEPOINT를 사용하거나 단일 외부 트랜잭션 내에서 작업하며, 모든 오류가 기록됩니다.

장점:

  • 완전한 무결성
  • 오류 감사

단점:

  • 더 복잡한 스크립트
  • 자동 저장 로직의 유지 관리가 약간 더 복잡함.