2010-04-23 2 views
1

NServiceBus를 사용하는 시스템을 구축하고 있으며 DataLayer는 Linq 2 SQL을 사용하고 있습니다.linq to sql with nservicebus 테이블 잠금 문제

시스템은 2 가지 서비스로 구성됩니다.

Service1은 NSB로부터 메시지를받습니다. 특정 조건이 새로운 NSB 메시지가 2 서비스로 전송이 충족되면 그것은 내 데이터베이스 에 표를 조회 표 에 레코드를 삽입합니다

이 서비스 1 메시지를 수신 할 때 서비스 2는 표 1에 또한 레코드를 업데이트합니다

및 다른 비 데이터베이스 관련 작업을 수행합니다. Service2는 장기 실행 프로세스입니다.

내가 가지고있는 문제는 Service2가 Table1의 레코드를 업데이트하는 순간 테이블이 잠겨 있다는 것입니다. Service2가 처리중인 모든 작업을 완료 할 때까지 잠김이 나타납니다. 즉, 데이터 인터페이스가 삭제 된 후에 잠금이 해제되지 않습니다.

이로 인해 Service1의 쿼리가 시간 초과되었습니다. Service2가 처리를 완료하면 Service1은 문제없이 다시 처리를 재개합니다.

그래서 예를 들어 서비스 1 코드처럼 보일 수 있습니다 :

int x =0; 
using (DataContext db = new DataContext()) 
{ 
    x = (from dp in db.Table1 select dp).Count(); // this line will timeout while service2 is processing 

    Table1 t = new Table1(); 
    t.Data = "test"; 
    db.Table1.InsertOnSubmit(t); 
    db.SubmitChanges(); 
} 

if(x % 50 == 0) 
    CallService2(); 

서비스 2의 코드처럼 보일 수 있습니다 다음 데이터 컨텍스트가있을 때 잠금이 해제되지 않는 이유 이해가 안

using (DataContext db = new DataContext()) 
{ 
    Table1 t = db.Table1.Where(t => t.id == myId); 
    t.Data = "updated"; 

    db.SubmitChanges(); 

} 

// I would have expected the lock to have been released at this point, but this is not the case. 

DoSomeLongRunningTasks(); 

// lock will be released once service2 exits 

Service2에 배치.

내가 호출 된 문제를 해결하기 위해 :

db.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED"); 

이 작동하지만, 나는 그것을 사용하는 행복하지 않다. 이 문제를 올바르게 해결하고 싶습니다.

이전에 이런 문제가 발생 했습니까? 어느 누구도 문제를 경험 한 적이 있습니까? datacontext가 삭제 된 후 잠금이 해제되지 않는 이유는 무엇입니까?

미리 감사드립니다.

p.s. 극도로 긴 게시물에 대해 유감입니다.

서비스 1 데이터베이스에 상자 기록을 추가 등의 운송과 같은 현실 세계 (틱) 상황이보고

:

편집

. 상자 레코드가 컨테이너 레코드에 추가됩니다 (컨테이너 레코드가없는 경우). 특정 숫자 또는 상자 레코드가있는 경우 운송 레코드를 작성하고 모든 컨테이너를 닫고 운송 레코드에 지정하십시오.

다음 운송 기록을 처리하려면 service2를 호출하십시오. service2에 대한 호출은 Bus.Send 호출이지만 사가의 일부일 수 있습니다. service2는 배가 할당 된 각 크레이트 레코드를 업데이트합니다. 다음에는 다른 운송 지침이 처리됩니다. service2가 처리되는 동안 다음 배송을 위해 더 많은 크레이트를받을 수 있지만 service2가 배송 처리를 완료 할 때까지 컨테이너에 지정할 수 없습니다.

답변

4

그 이유는 NServiceBus (TransactionScope에 대해 동일한)가 사용하는 기본 격리 수준이 전체 테이블을 잠그는 Serializable이기 때문입니다.

NServiceBus 수준에서 다른 격리 수준을 설정하려고합니다.

유창한 초기화 API를 사용하고 .MsmqTransport() 호출 후에 .IsolationLevel (IsolationLevel.ReadCommitted) 메서드를 호출하거나 다른 값을 전달해야합니다. 나는 그보다 낮게가는 것을 추천하지 않는다 (커밋되지 않은 것을 읽는 것과 같다).

위에서 설명한 시나리오에서 나는이 모든 것을 단일 처리기에 넣지 않았으며 최상위 수준의 흐름을 관리하기 위해 무용담을 선호했습니다. 처리기를 통해 중도 분리 경계를 깨뜨릴만큼 행복하기 때문에 .

희망이 있습니다.

+0

감사합니다. 그것은 내가 필요한 것입니다. – IGoor

+0

실제로 NSB 수준의 격리 수준을 읽기 커밋으로 변경해도 개선되지 않습니다. 나는 여전히 같은 문제를 경험한다. – IGoor

+1

그런 다음 데이터베이스의 실행 계획을보고 전체 테이블 스캔 결과 인 색인이 누락되어 있는지 확인하여 잠금을 업그레이드해야합니다. –