최근에 100,000 레코드에 대한 업데이트 쿼리를 실행했습니다. 쿼리가 실행되는 동안 실수를하고 네트워크 케이블을 빨리 뽑았습니다.
업데이트 쿼리를 수행
- 처리를 중지하고 완전히 롤백 하시겠습니까?
- 처리를 계속 완료하고 커밋 하시겠습니까?
- 처리를 중지하고 대상 행의 일부만 업데이트 된 상태로 두시겠습니까?
최근에 100,000 레코드에 대한 업데이트 쿼리를 실행했습니다. 쿼리가 실행되는 동안 실수를하고 네트워크 케이블을 빨리 뽑았습니다.
업데이트 쿼리를 수행
답변:
Nick과 Martin이 언급했듯이 쿼리의 최종 상태는 쿼리가 완료되기 전에 SQL Server가 네트워크 케이블 풀에 대해 알고 있는지 여부에 따라 다릅니다. 에서 온라인 (나는 그것이 이것에 대한 해당 주제에 있다는 것을 흥미 불구하고 2000 , 2005 , 2008 및 2008 R2 되지 2012 또는 2014 만) :
오류로 인해 트랜잭션이 성공적으로 완료되지 않으면 SQL Server는 자동으로 트랜잭션을 롤백하고 트랜잭션이 보유한 모든 리소스를 해제합니다. 데이터베이스 엔진 인스턴스에 대한 클라이언트의 네트워크 연결이 끊어지면 네트워크가 인스턴스에 중단을 알리면 연결에 대한 미해결 트랜잭션이 롤백됩니다. 클라이언트 응용 프로그램이 실패하거나 클라이언트 컴퓨터가 작동 중지되거나 다시 시작되면 연결도 끊어지고 네트워크에서 중단을 알릴 때 데이터베이스 엔진 인스턴스는 미해결 연결을 롤백합니다. 클라이언트가 응용 프로그램을 로그 오프하면 처리되지 않은 트랜잭션이 모두 롤백됩니다.
( 두 번째 문장의 단어 연결 은 아마도 거래일 것 입니다. 연결을 롤백하는 방법을 모르겠습니다.)
비슷한 방식으로, SQL Server는 서버가 예기치 않게 종료 된 후 복구 중에 트랜잭션을 실행 취소하거나 다시 실행할 수 있으며 이는 종료 시점의 트랜잭션 상태에 따라 다릅니다. 나는 사람들 이이 전술을 사용하여 당신이하려는 일을 수행하는 것을 보았습니다 (거래 취소). 그리고 서버가 다시 시작되었을 때 많은 작업이 단순히 다시 수행되었습니다 (무릎 부상 반응의 순 효과는 훨씬 더 가깝습니다) 예상보다 0으로).
따라서 네트워크 케이블을 잡아 당기거나 기계를 끄는 것과 같이 공황 상태에서 과감한 일을하는 대신 중요한 시스템에 대해 임시 쿼리를 실행하는 방법에 대해 더 나은 훈련을받을 것을 제안합니다. 예를 들어,
UPDATE dbo.sometable
-- where *oops* I forgot this part
이것을 가지고 :
BEGIN TRANSACTION;
UPDATE dbo.sometable
-- where *oops* I forgot this part
-- COMMIT TRANSACTION;
-- ROLLBACK TRANSACTION;
그런 다음 업데이트가 실제로 올바른 경우 COMMIT
부품을 강조 표시 하고 실행할 수 있습니다. 그렇지 않은 경우 침착하게 해당 ROLLBACK
부분을 강조 표시 하고 실행할 수 있습니다. SSMS 도구 팩 과 같은 추가 기능을 사용 하여 New Query
상용구를 포함하도록 템플릿을 편집 할 수도 있습니다 .
이제 트랜잭션이 다른 사용자를 차단하고 있기 때문에 쿼리를 실행 한 다음 커밋 또는 롤백 하지 않는 경우 여전히 문제가 발생할 수 있습니다 . 그러나 이것은 결정적으로 데이터를 수정하는 것보다 낫습니다.
물론 항상 그렇듯이 신뢰할 수있는 백업이 있어야합니다.
@ 아론이 맞습니다. 명령을 내리기 전에 거래를 만드는 것이 가장 좋습니다. 기억이 나지 않으면 Tools-Options
설정 으로 이동 하여을 켜십시오 SET IMPLICIT_TRANSACTIONS
. 특정 명령이 실행 되 자마자 자동으로 트랜잭션이 시작됩니다. 여기에는 UPDATE
, DELETE
이 것 모든 명령의 상당히 전체 목록 것으로 보인다 등 "change"
뭔가. SELECT
또한 목록에 포함되어 will
거래를 시작합니다. 트랜잭션을 시작하는 명령의 전체 목록이 여기에서 설정 됩니다 . 이미 시작된 트랜잭션은 생성하지 않습니다. 이제 단점은 COMMIT
변경 한 후에 기억해야한다는 것입니다 .
참고 : @Aaron의 제안에 따라 다시 강조하겠습니다.
This is very important! You will have to remember to COMMIT after any change made!
기본적으로 당신을 잊고 떨어져 거래되고 BEGIN
트랜잭션과에 잊고에 대해 뭔가를 엉망으로 COMMIT
거래하고 당신이 그것을두고 연 다음 날 떠날 경우가 걸려 가지고. 트랜잭션을 롤백한다고 생각하는 쿼리 창을 닫는 것으로 테스트했지만 트랜잭션을 커밋하거나 롤백하려는 경우 프롬프트가 표시되었습니다.
SELECT
를 시작합니다 (이것은 귀하가 게시 한 링크에도 문서화되어 있음)
나는 그것이 정말로 달려 있다고 생각한다 :
네트워크 케이블을 분리하기 전에 명령이 이미 서버에 도달 한 경우 명령은 계속 정상적으로 실행됩니다.
모든 업데이트 명령을 캡슐화하는 TransactionScope (.Net에서 사용되며 다른 언어는 확실하지 않음)가있는 경우 transactionScope.Complete ()가 실행되지 않았지만 보장되지 않는 경우에만 트랜잭션이 커밋되지 않도록 중지 할 수 있습니다. .