특정 상황에서 모든 작업을 취소하고 호출자에게 오류 코드를 반환 할 수 있도록 저장 지점을 설정해야하는 저장 프로 시저가 있습니다. , 수락/커밋하고 호출자에게 성공을 반환합니다. 그러나 호출자가 이미 트랜잭션을 시작했는지 여부를 확인해야합니다. 의사는이 주제에 대해 매우 혼란 스럽습니다. 여기 내가 생각하는대로 작동하지만, 모든 파급 효과가 확실하지 않습니다.SAVE TRANSACTION 대 BEGIN TRANSACTION (SQL Server) 트랜잭션을 멋지게 중첩하는 방법
것은 -이 Stored Procedure (SP)
은 다른 사람이 호출합니다. 따라서 거래를 시작했는지 여부는 알 수 없습니다 ... 사용자가 내 SP를 사용하기 위해 거래를 시작하도록 요구하더라도 여전히 Save Points
의 올바른 사용에 대한 질문이 있습니다 ...
내 SP는 거래가 진행 중인지 여부를 테스트하고 그렇지 않은 경우 BEGIN TRANSACTION
으로 시작합니다. 트랜잭션이 이미 진행 중이면 대신 SAVE TRANSACTION MySavePointName
으로 저장 지점을 만들고이 사실을 저장합니다.
그런 다음 변경 사항을 롤백해야한다면 BEGIN TRANSACTION
을 먼저 수행하면 ROLLBACK TRANSACTION
이됩니다. 세이브 포인트를했다면 ROLLBACK TRANSACTION MySavePointName
입니다. 이 시나리오는 훌륭하게 작동하는 것 같습니다.
여기 내가 다소 혼란스러워하는 곳입니다. 제가 한 일을 계속하고 싶다면, 제가 거래를 시작하면 COMMIT TRANSACTION
을 실행할 것입니다. 하지만 저장 지점을 만들었습니까? 나는 COMMIT TRANSACTION MySavePointName
을 시도했지만 다음 호출자는 트랜잭션을 커밋을 시도하고 오류 가져옵니다 그래서
The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
그때 궁금하네요 - 세이브 포인트 롤백 할 수 있습니다 (작업 : ROLLBACK TRANSACTION MySavePointName
가 호출자의 롤백 할 것이다 트랜잭션). 하지만 아마도 "커밋"할 필요가 없을 것입니다. 원래 트랜잭션이 커밋 (또는 롤백)되면 다시 롤백 할 필요가 없기 때문에 그대로 유지됩니다.
거래를 "중첩"하는 "더 좋은"방법이있는 경우 빛을 비추십시오. BEGIN TRANSACTION
으로 중첩하는 방법을 알아 내지 못했지만 내부 트랜잭션 만 롤백하거나 커밋합니다. ROLLBACK
은 항상 상단 트랜잭션으로 롤백되며, COMMIT
은 단순히 @@trancount
만큼 감소합니다.
귀하의 발견은 답변으로 게시 가치가있을 수도 있습니다. –
@Andriy Ok, 그게 내가 한 짓이야. 내 편집을 제거하고 대신 대답으로 사용 했어. 감사. –