다른 거래를 차단하는 잠자는 SPID


16

실제로 발생하는 차단을 추적하는 데 문제가 있습니다.

루트 차단 SPID의 상태는 'sleeping'이고 cmd는 'AWAITING COMMAND'이며 sqltextis SET TRANSACTION ISOLATION LEVEL READ COMMITTED입니다.

차단 된 트랜잭션 수별 상위 트랜잭션 보고서를 볼 때 차단 SQL 문은 '-'입니다.

SQL에 대한 추적을 수행했으며 차단이 루트 차단 SPID를 추적 할 때 실제로 어디서나 나를 이끌지 못했습니다. 마지막 추적 명령문은 sqltext위와 동일합니다 SET TRANSACTION ISOLATION LEVEL READ COMMITTED.

TRY / CATCH BEGIN TRAN / COMMIT TRAN / ROLLBACK TRAN 문이 있는지 확인할 수있는 모든 관련 저장 프로 시저를 확인했습니다 (우리는 실행중인 독립 문이 없도록 모든 것에 대해 저장 프로 시저를 사용합니다). 이 문제는 지난 24 시간 동안 발생하기 시작했으며 아무도 시스템을 변경했다고 주장하지 않습니다.

해결책 : 거의 사용되지 않는 저장 프로 시저 중 하나에 삽입 오류 (열 수가 일치하지 않음)가 있었지만 여전히 정확히 무슨 일이 일어나고 있는지 혼란 스럽습니다.

모든 추적 정보를 볼 때이 저장 프로 시저에 대한 EXEC 문이 때때로 나열되었지만 차단 SPID에서 BLOCK이 발생하기 직전에 절대로 없었습니다. 블로킹을 시작할 때 추적이 실행을 기록하지 않은 것 같습니다 (또는 그 안의 명령문 중 하나). 그러나 추적이 실행을 기록하고 차단이 발생하지 않은 다른 시간이 있습니다.

저장 프로 시저 오류 보고서는 사용자가 제공 한 것으로 여러 EXEC 문을 추적하여 SSMS에서 실행할 수있었습니다. 내가 그들을 실행했을 때 우리는 막히지 않았거나 멈추지 않았습니다. 예상대로 실행되었습니다 (캐치 블록이 시작되고 오류가 발생한 후 트랜잭션을 롤백했습니다). 저장 프로 시저 수정을 해결 한 후에도 문제가 다시 나타나지 않습니다.


차단 SPID의 호스트 이름이 전혀 도움이되지 않는다고 가정합니다.
— Jon Seigel

아니요, 웹 서버 중 하나의 IP 일뿐입니다. 로그인 / 등록 프로세스 (오류가 발생했다고 생각되는) 동안 각 SPROC 호출에 대한 모든 SQL 로그인을 별도의 사용자 이름으로 변경하는 또 다른 아이디어가 있습니다. 차단을 유발할 수있는 SPROC를 분리하는 데 도움이됩니다.
— Brad

1
TRY / CATCH는 컴파일 오류를 포착하지 않으며 일치하지 않는 열 삽입은 컴파일 오류입니다. 이것은 또한 많은 XX : Completed 프로파일 러 이벤트를 트리거하지 않습니다.
— Remus Rusanu

1
천재 개발자가 INSERT INTO [table] SELECT * from [othertable]을 사용하고 피어에 걸리지 않았기 때문에 실제로 컴파일 오류가 아닙니다. 3 개의 동시 세션에서 ColdFusion에서 1000 번 개발에 대해 SPROC를 실행했으며 프로덕션에서와 같이 트랜잭션을 열지 않았습니다.
— Brad

답변:


10

의견에서, 당신은 SQL 쿼리를 중단 한 클라이언트 측 명령 시간 초과가 있다고 생각합니다. 연결 풀링으로 인해 SQL Server에서 연결이 열려 있기 때문에 트랜잭션을 롤백하지 않습니다.

따라서 SET XACT_ABORT ON을 사용하거나 클라이언트 롤백 코드를 추가해야합니다.

모든 세부 사항 은 SQL Server Transaction Timeout 을 참조하십시오.


모든 SPROC에는 TRY / CATCH 블록과 BEGIN TRAN / COMMIT TRAN / ROLLBACK TRAN 문이 포함되어 있으며 ROLLBACK은 CATCH에 있습니다. XACT_ABORT가 여전히 효과가 있습니까?
— Brad

@ 브래드 : 예. 내 링크를 참조하십시오. 캐치 블록은 CommandTimeout에서 히트하지 않습니다
— gbn

gbn : 감사합니다. 여전히 혼란 스러워요. 연결이 시간 초과되지 않도록 설정되었습니다 (0). 따라서 연결을 재사용하고 연결이 오류 (TRY / CATCH 및 TRAN 블록이 있음)와 함께 SPROC를 실행하면 CATCH 블록에서 ROLLBACK을 절대 실행할 수 없으므로 테이블을 잠그고 트랜잭션을 유지합니다. 열다? 그건 말이되지 않습니다.
— 브래드

@Brad : 오류가있는 SPROC가 CATCH 블록에 도달합니다. 나는 달리 말하거나 다르게 말하지 않았다. 그러나 내 링크는 ConnectionTimeout과 다른 CommandTimeout이 있으면 어떻게되는지 알려줍니다. 클라이언트가 "중단"이라고 말하고 SQL Server가 처리를 중지합니다. Ergo, CATCH 블록 또는 롤백 또는 커밋은 절대 발생하지 않습니다
— gbn

CommandTimeout이 지정되어 있다고 생각하지 않습니다. 우리의 모든 스토어드 프로시 저는 sqlstress를 사용하여 테스트 중이며 10 명의 사용자 10 회 (최소한) 반복에서 1000ms 미만으로 수행해야합니다. 나는 아직도 일어난 일에 대해 매우 혼란 스럽지만 문제가 발견 된 것으로 질문을 업데이트하고 있습니다.
— 브래드

9

sys.dm_exec_connections에서 most_recent_sql_handle을 사용하여 마지막으로 실행 된 명령문을보십시오.

SELECT  t.text,
        QUOTENAME(OBJECT_SCHEMA_NAME(t.objectid, t.dbid)) + '.'
        + QUOTENAME(OBJECT_NAME(t.objectid, t.dbid)) proc_name,
        c.connect_time,
        s.last_request_start_time,
        s.last_request_end_time,
        s.status
FROM    sys.dm_exec_connections c
JOIN    sys.dm_exec_sessions s
        ON c.session_id = s.session_id
CROSS APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) t
WHERE   c.session_id = 72;--your blocking spid

또한 해당 spid에 대한 미결 거래가 있는지 확인하십시오.

SELECT  st.transaction_id,
        at.name,
        at.transaction_begin_time,
        at.transaction_state,
        at.transaction_status
FROM    sys.dm_tran_session_transactions st
JOIN    sys.dm_tran_active_transactions at
        ON st.transaction_id = at.transaction_id
WHERE   st.session_id = 72;--your blocking spid

또한 DBCC INPUTBUFFER(spid)마지막으로 실행 된 SQL을 볼 수도 있습니다 .
— Mike Fal

나는 그것들을 모두 사용했고 마지막 명령은 항상 원래 게시물에 넣은 것입니다 : SET TRANSACTION ISOLATION LEVEL READ COMMITTED. 또한 DBCC OPENTRAN을 실행했으며 차단 PID에 대한 열린 트랜잭션이 있음을 알 수 있습니다.
— Brad

명령문이 실제로 프로 시저의 일부인 경우 첫 번째 선택에서도 프로 시저 이름을 제공합니다.
— Sebastian Meine

우리는 우리 웹 서버에서 임시 쿼리를 사용하지 않을 것을 확신하며, WHERE 절이 없어도 첫 번째 쿼리를 실행할 때 소수의 SQL 세션에서만 명명 된 SPROC 만 얻습니다. 나머지 열은 NULL입니다.
— Brad

'SET TRANSACTION ISOLATION LEVEL READ COMMITTED'라는 세션이 많이 있으며 모든 세션이 ColdFusion (웹 서버에서 사용되는 기본 스크립팅)에서 나왔습니다. 유휴 상태 일 때 연결을 유지하기 위해 해당 연결을 유지하도록 설정된 상태에서 ColdFusion을 사용했을 수 있습니다.
— Brad

4

Adam Machanic의 sp_whoisactive를 사용해 보셨습니까 ? 외부 명령이 실제로 proc 내에 있는지 확인하는 옵션이 있습니다. 응용 프로그램이 트랜잭션을 커밋하는 대신 열려있는 것일 수 있습니다. DBCC OPENTRAN 도 살펴보십시오 .


DBCC OPENTRAN에 감사드립니다. 블로킹 PID에 공개 트랜잭션이 있지만 더 이상 세부 정보가 없다고 알려줍니다. sp_whoisactive는 내가 직접 얻을 수 있었던 것과 같은 정보를 차단 된 프로세스에 반환합니다. 'SET TRANSACTION ISOLATION LEVEL READ COMMITTED'이외의 진행 상황에 대한 자세한 내용은 아직 없습니다.
— Brad
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.