Ado.net TransactionScope를 사용하는 대량 사이트 vs nolock에서 실행 관리를 직접 읽으십시오.

StackOverflow https://stackoverflow.com/questions/628004

문제

그의 블로그에서 Omar의 흥미로운 기사를 읽으십시오. LINQ에서 SQL을 해결하지 못한 읽기를 사용하여 트랜잭션 교착 상태 및 쿼리 타임 아웃 문제를 해결합니다. 그리고 결국 Javed Hasan은 대량 부지의 Nolock 상황에 대한 그의 해결책에 대해 그와 논쟁하기 시작했습니다.

여기서 해결을 시도하는 문제는 SQL Sense에서 NOLOCK 또는 사용 설정 트랜잭션 레벨 읽기를 사용해야하는 SQL Sense에서 커밋되지 않으면 DB의 대량 행에서 고정되어 오류가 발생합니다. 사용 된 기술은 LINQ2SQL이므로 문제는 위의 일이 발생하지 않도록 C# 데이터 액세스 코드에서 어떻게 달성 할 수 있습니까?

기본적으로 Omar는 실제 사이트에서 작업하고 테스트하여 SQLPROFILER와 같은 도구를 사용하여 솔루션을 제공하는 반면 Javed Hasan은 MSDN 문서와 Scott Hanselman의 블로그 게시물 등을 사용하여 솔루션을 제공합니다.

Omar는 다음을 사용하는 것을 제안합니다

using (var db = new DropthingsDataContext2())
{
  db.Connection.Open();
  db.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");

  var user = db.aspnet_Users.First();
  var pages = user.Pages.ToList();
}

Javed Hasan은 제안합니다

using (new TransactionScope(TransactionScopeOption.Required, 
  new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
{
 //Your db Operation
}

StatckoverFlow와 같은 대량 사이트 에서이 특정 문제에 대해 여러분이 무엇을하는지 알고 싶거나 Jeff와 그들의 사람들이 이와 관련하여 무엇을 했습니까?

편집하다: 첫 번째 게시물을 읽은 후 Omar의 게시물에서 몇 가지를 지적하고 싶습니다.

  1. 그는 자신의 접근 방식으로 연결 문제를 겪었지만 그것을 해결하고 그의 게시물을 보았습니다.
  2. 더 중요한 것은 그가 Ado.net Transaction Way를 사용하려고 시도하고 Scott Hanselman이 자신의 블로그에 쓴 내용을 시도했지만, 대량 사이트에서는 작동하지 않으며 성능이 상당히 저하됩니다. Omar는 "System.Transactions는 상당한 오버 헤드를 가지고 있다고 말했다. 나는 CPU가 100% Go를 100%, REQ/SEC가 1/10으로 내려 가지 않고도 대량 웹 사이트에서 사용할 수 없었습니다. 엔터프라이즈 응용 프로그램을 위해 만들어졌습니다. 볼륨 웹 사이트. "
도움이 되었습니까?

해결책

우선, 커밋되지 않은 읽기를 피하면 많은 문제가 발생할 수 있습니다. 훨씬 더 나은 접근 방식은 데이터베이스를 다음으로 설정하는 것입니다. 스냅 샷 격리. 이것이 제프가 한 일입니다.

Jeff는 기본적으로 다음과 같이 말했습니다 : "Bla Bla Bla, Be Real, Bla Bla Bla, Database Teoreticians, Bla Bla Bla, Read Uncommitted는 데이터 일관성이 필요하지 않은 실제 생산 앱에 유용 할 수 있습니다." Jeff는 DBA가 아니며 운 좋게도 여기에 많은 DBA가 있습니다.

Omar의 접근 방식의 문제점은 웹 사이트에서 혼란을 일으킬 수있는 연결 풀에 "커밋되지 않은"격리 레벨과 연결을 유출 할 수 있다는 것입니다. 의미 무작위 진술은 read incommitted에서 실행될 수 있습니다.

MS를 처리 할 때 연결에 대한 물건을 청소할 수 있기 때문에 Javed 접근 방식이 훨씬 나을 것입니다.

편집하다 Javed의 접근 방식에 성능 문제가있는 경우 자신의 트랜잭션 관리자를 롤링하는 것을 볼 수 있습니다.

아마도 당신이하고 싶은 일 :

  • 현재 트랜잭션 스택을 보관하십시오
  • 거래가 커밋 될 때 제작자 스레드에 있는지 확인하십시오.
  • 거래에 대한 이전 상태로 거래 격리를 재설정합니다.
  • 거래가 커밋되지 않은 경우 폐지에 대한 롤백.
  • 중첩 롤백을 지원합니다.

다른 팁

저는 Microsoft의 SQL Server 그룹의 도구 팀 개발자입니다. 많은 응용 프로그램은 트랜잭션 일관성에 매우 민감하지 않습니다. 특히보고하는 앱이나 때때로 일관성이없는 데이터가 세계의 종말이 아닌 앱을 작성하는 경우. 물론, 재무 애플리케이션을 작성하거나 데이터 불일치에 대한 내성이 매우 낮은 다른 내용을 작성하는 경우 다른 솔루션을 탐색하고 싶을 것입니다.

커밋되지 않은 읽기를 사용하도록 선택하면 편리한 솔루션을 블로그로 작성했습니다 C#에서 확장 방법을 사용합니다.

{내 (가난한) 평판은 댓글을 게시하지 못하게하므로 답변으로}}

트랜잭션 블록 내에서 Transactions를 통해 IrolationLevel을 사용하고 새로운 LINQ 컨텍스트를 작성하는 경우 SQL Server는 DTC를 호출하여 트랜잭션을 조정하려고합니다. 그것은 방금 나에게 일어 났고 예상치 못한 일이었습니다.

.NET의 트랜잭션 및 DTC의 (어쨌든 놀라운) 부작용과 관련 하여이 문서 .NET Framework 2.0에서 시스템 소개 Juval Lowy는 사물을 잘 설명하고 여전히 완전히 유효합니다 (.NET4). 읽을 가치가 있습니다. (나는 또한 의견을 게시했을 것입니다 ... 가능하다면.)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top