SQL Server 트랜잭션 시간 초과


9

SQL Server 2008 R2에서 트랜잭션과 관련된 데이터베이스 수정에 시간 초과가 발생하는 방법이 있습니까? 애플리케이션 코드가 중단되거나 예외가 발생하여 롤백 또는 커밋을 수행하지 못하는 시나리오가 있습니다. 그러면 트랜잭션이 완료되기를 기다리는 다른 세션이 정지됩니다.

답변:


20

마크의 답변 연장 중 ...

클라이언트 시간 초과 이벤트가 발생하면 (예 : .net CommandTimeout) 클라이언트는 "ABORT"를 SQL Server로 보냅니다. 그런 다음 SQL Server는 단순히 쿼리 처리를 포기합니다. 롤백 된 트랜잭션이없고 잠금이 해제되지 않습니다.

이제 연결이 연결 풀로 반환되므로 SQL Server에서 닫히지 않습니다. 이 문제가 발생하면 (KILL 또는 클라이언트 재부팅 등을 통해) 거래 + 잠금이 해제됩니다. sp_reset_connection은 광고한다고하더라도이를 지우지 않거나 지우지 않습니다.

중단으로 인한 이물질은 다른 프로세스를 차단합니다.

SQL Server에서 클라이언트 시간 초과시 트랜잭션 + 잠금을 지우는 방법 (엄격히 ABORT 이벤트)은 SET XACT_ABORT ON을 사용하는 것입니다.

SSMS에서 2 개의 쿼리 창을 여는 지 확인할 수 있습니다.

창 1 :

Query..Query Options 메뉴에서 시간 제한을 5 초로 설정 한 다음

BEGIN TRAN
UPDATE sometable WITH (TABLOCKX) SET foo = foo WHERE 1 = 0;
WAITFOR DELAY '00:00:10' -- just has to be longer then timeout

창 2, 이것은 영원히 기다릴 것입니다 (또는 타임 아웃을 치십시오)

SELECT * FROM sometable

SET XACT_ABORT ON에는 흥미로운 부작용도 있습니다.

  • 암시 적 롤백에서 @@ TRANCOUNT가 0으로 설정되었지만 오류 266이 억제됩니다 (이는 @@ TRANCOUNT가 저장 프로 시저에서 시작 및 종료 될 때 발생합니다).
  • XACT_STATE는 -1입니다 ( "두 메드").

이 조합은 부분 커밋 / 롤백에 SAVEPOINTS를 사용할 수는 없지만 (정확한 동작을 기억할 수는 없지만) 의미합니다. 나에게 맞는

SET XACT_ABORT의 SO 링크 :

중첩 된 저장된 proc에서 :

sp_reset_connection에서 :


미래는 안녕을 말한다! "sp_reset_connection은 광고를한다고하더라도이를 지우지 않거나 지우지 않습니다."-최신 버전의 SQL Server에서는 더 이상 이것이 사실이라고 생각하지 않습니까?
kamilk

11

문제에 대한 설명에 정보가 충분하지 않아 이것이 최선의 조언인지 100 % 확신하기 때문에 주저없이 대답하고 있습니다. " 예외를 행 하거나 던짐"은 문제의 원인을 제대로 이해하지 못했음을 나타내므로주의해서 진행하십시오.

이것에 대한 가장 간단한 해결책은 아마도입니다 SET XACT_ABORT ON.

XACT_ABORT런타임 오류 발생시 SQL Server가 트랜잭션을 롤백할지 여부를 결정합니다. 기본값 SET XACT_ABORT OFF은 상위 트랜잭션을 열어두고 오류를 일으킨 명령문 만 롤백합니다.

기본 설정의 "gotcha"부작용은 시간 초과로 인해 클라이언트가 처리하고 롤백 할 책임이있는 열린 트랜잭션과 정확히 동일한 문제를 일으킬 수 있다는 것입니다. 클라이언트가 시도 / 캐치 / 롤백을 시도하지 않으면 트랜잭션은의 매우 폭력적인 상황에 참석할 때까지 열려 있습니다 (@gbn 인용) KILL <spid>.

SQL Server의 오류 처리에 대한 Erland Sommarskog의 기사 에는 종종 이러한 시나리오 등을 처리하는 데 필요한 모든 배경과 전략이 포함되어 있습니다.

편집 (설명 다음에) : 열린 트랜잭션을 식별하기 위해 sp_whoisactive 가 가장 완벽한 기능 일 것입니다.


일부 인터넷 검색에서 중단이 발생했을 때 열린 트랜잭션을 찾는 방법을 찾았습니다. 아마도 이것이 최고의 솔루션입니다. 즉 코드에서 닫히지 않은 트랜잭션의 원인을 찾아 코드의 구멍을 수정하는 것입니다. 다른 사람을 위해 참조하십시오. DBCC OPENTRAN은 가장 오래된 활성 트랜잭션-> msdn.microsoft.com/en-us/library/ms182792.aspx를 반환 합니까? 아니면 이와 비슷한 것입니까? -> weblogs.sqlteam.com/mladenp/archive/2008/04/29/…
David Gray Wright

난 항상 Erland가 SET XACT_ABORT sommarskog.se/error-handling-I.html#XACT_ABORT
gbn에
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.