Stack Overflow SQL Server 2005 데이터베이스에서 악성이지만 드문 교착 상태가 발생했습니다.
프로파일 러를 연결하고 교착 상태 문제 해결에 대한이 훌륭한 기사를 사용하여 추적 프로파일을 설정 하고 여러 예제를 캡처했습니다. 이상한 점은 교착 상태 쓰기가 항상 동일 하다는 것입니다 .
UPDATE [dbo].[Posts]
SET [AnswerCount] = @p1, [LastActivityDate] = @p2, [LastActivityUserId] = @p3
WHERE [Id] = @p0
다른 교착 상태 문은 다양하지만 일반적으로 posts 테이블 을 간단하고 간단하게 읽습니다 . 이것은 항상 교착 상태로 죽습니다. 여기에 예가 있습니다.
SELECT
[t0].[Id], [t0].[PostTypeId], [t0].[Score], [t0].[Views], [t0].[AnswerCount],
[t0].[AcceptedAnswerId], [t0].[IsLocked], [t0].[IsLockedEdit], [t0].[ParentId],
[t0].[CurrentRevisionId], [t0].[FirstRevisionId], [t0].[LockedReason],
[t0].[LastActivityDate], [t0].[LastActivityUserId]
FROM [dbo].[Posts] AS [t0]
WHERE [t0].[ParentId] = @p0
명확하게 말하면, 쓰기 / 쓰기 교착 상태가 아니라 읽기 / 쓰기입니다.
현재 LINQ와 매개 변수화 된 SQL 쿼리가 혼합되어 있습니다. with (nolock)
모든 SQL 쿼리에 추가 했습니다. 이것은 일부 도움이되었을 수 있습니다. 또한 어제 수정 한 (매우) 잘못 작성된 배지 쿼리가 하나있었습니다. 매번 실행하는 데 20 초 이상이 걸리고 그 위에 매분 실행되었습니다. 이것이 잠금 문제의 원인이되기를 바랬습니다!
불행히도 약 2 시간 전에 또 다른 교착 상태 오류가 발생했습니다. 똑같은 증상, 똑같은 범인이 쓴다.
정말 이상한 점은 위에서 본 잠금 쓰기 SQL 문이 매우 특정한 코드 경로의 일부라는 것입니다. 그것은 것 에만 새 응답이 질문에 추가 될 때 실행 - 그것은 새 응답 수와 마지막 날짜 / 사용자와 부모의 질문을 업데이트합니다. 이것은 분명히 우리가 수행하는 엄청난 수의 읽기에 비해 그렇게 일반적이지 않습니다! 내가 말할 수있는 한, 우리는 앱 어디에서나 엄청난 수의 쓰기를하고 있지 않습니다.
NOLOCK이 일종의 거대한 망치라는 것을 알고 있지만 여기서 실행하는 대부분의 쿼리는 정확할 필요가 없습니다. 사용자 프로필이 몇 초가 지난 경우에도 신경 쓰시겠습니까?
Linq와 함께 NOLOCK을 사용하는 것은 Scott Hanselman이 여기에서 설명 하는 것처럼 조금 더 어렵습니다 .
우리는 사용의 아이디어를 유혹하고 있습니다
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
모든 LINQ 쿼리가이 세트를 갖도록 기본 데이터베이스 컨텍스트에서 그것 없이는 우리가 만드는 모든 LINQ 호출 (대부분의 간단한 읽기 호출)을 3-4 줄 트랜잭션 코드 블록으로 래핑해야합니다.
SQL 2005의 사소한 읽기가 쓰기에 교착 상태가 될 수 있다는 사실에 약간 실망한 것 같습니다. 쓰기 / 쓰기 교착 상태가 큰 문제라는 것을 알 수 있지만 읽습니까? 우리는 여기서 은행 사이트를 운영하지 않으며 매번 완벽한 정확성이 필요하지 않습니다.
아이디어? 생각?
모든 작업에 대해 새 LINQ to SQL DataContext 개체를 인스턴스화하고 있습니까? 아니면 모든 호출에 대해 동일한 정적 컨텍스트를 공유하고 있습니까?
Jeremy, 우리는 대부분의 경우 기본 컨트롤러에서 하나의 정적 데이터 컨텍스트를 공유합니다.
private DBContext _db;
/// <summary>
/// Gets the DataContext to be used by a Request's controllers.
/// </summary>
public DBContext DB
{
get
{
if (_db == null)
{
_db = new DBContext() { SessionName = GetType().Name };
//_db.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
}
return _db;
}
}
모든 컨트롤러에 대해 또는 페이지별로 또는 .. 더 자주 새 컨텍스트를 만드는 것이 좋습니까?