2013-07-04 1 views
2

배치에 대한 2 일간의 테스트가 끝나고 롤백을 시도한 후 잡아보십시오. 내 마음은 여전히 ​​모호합니다. 나는 내 질문을 정리하기 위해 내가 한 일을 두 단계로 나눈다. 다시배치를 쉽게 롤백 할 수 없습니까?

1 롤 온라인 책이 설명하는 배치, 일괄, 문이 다시에만 배치가 트랜잭션과 배치에 오류가 트랜잭션이 롤백 원인을 제외하고 롤이 될 수 없습니다 실행.

그래서 나는

begin transaction 
    create table A ... 
    insert into A values... 
    insert into A values... (error here!) 
    insert into A values... 
    GO 
rollback 

이 오류 출력 작업처럼 트랜잭션에 배치를 넣고 더 테이블

(1 row(s) affected) 
Msg 213, Level 16, State 1, Line 5 
Column name or number of supplied values does not match table definition. 

Msg 208, Level 16, State 1, Line 1 
Invalid object name 'A'. 

을 생성하지 않았다 그러나, 롤백은 트랜잭션 어쨌든에도 오류가 실행되지 않습니다 . 이 경우에 대처하기 위해, 나는 문이 여기 허용하지 않습니다 2.

2. 사용 TRY ... CATCH

BEGIN TRY 
    begin transaction 
    create table A ... 
    insert into A values... 
    insert into A values... (error here!) 
    insert into A values... 
    --GO 
END TRY 
BEGIN CATCH 
    ROLLBACK 
END CATCH 

이 시간으로 TRY ... CATCH를 사용 더 이상. S * o이 경우 전체 일괄 처리가 BEGIN TRYEND TRY 사이입니까? * 또한 예상대로 결과가 아닙니다. CREATE TABLE과 첫 번째 삽입물은 여전히 ​​실행되었고 롤백되지 않았습니다. 다시 검색했습니다. touch commit 전에 커밋되지 않은 명령문을 기록하기 위해서는 SET XACT_ABORT ON이 필요합니다. 내가 여기서 이해하고있는 것이 옳은가? 그렇다면이 경우 커밋 문을 추가하지 않았습니다.

그건 그렇고, 테스트는 SQL SERVER 2012에서 수행됩니다. 어떤 설명을 해주셔서 감사합니다!

+0

가능한 복제본 [SQL Server - 트랜잭션 롤백시 오류가 있습니까?] (http://stackoverflow.com/questions/1749719/sql-server-transactions-roll-back-on-error) –

+0

GO 첫 번째 내가 아는 한 블록은 필요하지 않습니다. –

+0

GO를 제거하는 경우 트랜잭션 대기 시간 때문에 롤백을 적용 할 수 없습니다. – FebWind

답변

1

는 GO 문이 MSDN article에 metioned로 시도 및 캐치 같은 배치의 일부가 될 수 있어야한다는 것입니다 허용하지 않는 이유. 그것은 말한다; gbns 질문 Nested stored procedures containing TRY CATCH ROLLBACK pattern?에 대한 답변에서 그는 (및 이유)의 사용을 포함하여 트랜잭션을 처리하기위한 XACT_ABORT 및 기타 멋진을 자신의 패턴/템플릿 설명으로이 문제를 처리하는 방법에 대한 다른 아이디어를

"Each TRY…CATCH construct must be inside a single batch, stored procedure, or trigger. For example, you cannot place a TRY block in one batch and the associated CATCH block in another batch. The following script would generate an error:"

BEGIN TRY 
    SELECT * 
     FROM sys.messages 
     WHERE message_id = 21; 
END TRY 
GO 
-- The previous GO breaks the script into two batches, 
-- generating syntax errors. The script runs if this GO 
-- is removed. 
BEGIN CATCH 
    SELECT ERROR_NUMBER() AS ErrorNumber; 
END CATCH; 
GO 

는 봐 풍모. 나는 또한 gbns의 관련 링크를 읽는 것이 좋습니다 답변 :

같은 질문에 대한 Aaron Betrand의 답변은 Erland Somarsskog의 012b과 매우 비슷하며 gbn의 대답과 매우 비슷합니다.

원래 질문의 제목이 중첩 된 트랜잭션과 관련되어 있다고해도, 나는 믿을 수있는 상황에서 여전히 적용 가능합니다.

0

스크립트의 초기에 SET XACT_ABORT ON을 사용해보십시오.

체크 아웃 XACT_ABORT MDSN 참조 페이지 here

관련 문제