2014-12-19 3 views
0

서비스 계층이있는 MVC 응용 프로그램에서 Entity Framework 6.1.1 (SQL Server 백 엔드)을 사용하고 있습니다.Entity Framework에서 사용 가능한 다음 행을 얻습니다.

데이터베이스에서 행을 가져 오기 위해 서비스 계층에서 데이터베이스를 읽으려는 경우, 다음 읽기를 중지하도록 처리 중임을 알리기 위해 무언가를 업데이트 한 다음 반환하십시오.

기본적으로 2 명의 사용자가 동일한 서비스를 호출하는 경우 첫 번째 읽기가 레코드를 업데이트 할 때 서로 다른 행을 갖게됩니다 (열 "처리 중"을 true로 변경한다고 가정). 두 번째 읽기는이 레코드를 건너 뛰고 다음 레코드로 이동합니다.

EF에서 일반적인 linq 쿼리를 사용하여이 작업을 수행 할 수있는 방법을 생각할 수 없습니다. 내가 그것을 할 수있는 유일한 방법은 저장 프로 시저를 사용하는 것입니다. 나는 SP에서 그것을하는 방법을 아직 100 % 확실하지는 않지만. 그게 유일한 옵션이라면 나는 더 조사 할 것이다.

EF를 사용하여이 작업을 수행 할 수 있습니까?

+0

이 모든 것이 실제로 실제로 너무 빠르다는 이유는 무엇입니까? – Derek

+0

Processing <> true 인 행만 선택하고 다음 행을 그렇게 얻을 수 있습니까? – timothyclifford

+0

@Derek 바쁜 웹 사이트에서는 확실히 발생합니다. 읽기를 수행 한 다음 업데이트를 수행하는 데 걸리는 시간이 변경됩니다. – eyeballpaul

답변

0

이 기사를 살펴보십시오. 그것의 SQL 트랜잭션 격리 수준.

SQl의 기본 격리 수준은 입니다. READ COMMITED입니다.

이것은 테이블의 행에 대한 변경을 커밋 할 때 동일한 시간 프레임의 일부분에서 이후의 모든 쿼리가 쿼리를 실행하기 전에 트랜잭션이 완료 될 때까지 기다려야 함을 의미합니다.

여기 링크입니다 : -이 도움이

http://gavindraper.com/2012/02/18/sql-server-isolation-levels-by-example/

희망,

나는 당신이 가진 잘못된 길을가는 확신 해요.

+0

답변 해 주셔서 감사합니다. 왜 내가 잘못된 길로 가는지 조언 해 줄 수 있습니까? 기본적으로 처리 할 행 수가있는 테이블이 있습니다. 그 (것)들을위한 다음 행을 위해, 가공 할 것이다 그것을 일할 것이다. 많은 사용자가 있고, 동일한 rowm에 작동 할 수 없다. – eyeballpaul

+0

또한, "읽힌 투입된"는 과태이다. "선택"이 끝날 때까지 시작해야한다고 생각합니다. 실제로 다음과 같이 트랜잭션 스코프를 변경할 수 있다고 생각합니다. http://stackoverflow.com/questions/13404061/lock-a-table-on-read-using-entity-framework을 잠 그려면 – eyeballpaul

0

이 솔루션의 실행 가능성에 대해 확신하지는 않지만 간단하며 데이터 계층 (데이터베이스 아님)으로 인해 서비스 성능이 저하 될 수 있습니다.

public class MyDbContext : DbContext 
{ 
    private DbSet<Data> DataTable { get { return this.Set<Data>(); } } 

    private static object lockObject = new object(); 
    public Data GetDataToProcess() 
    { 
     lock (lockObject) 
     { 
      Data data = this.DataTable.FirstOrDefault(d => d.Processing == false); 
      data.Processing = true; 
      this.SaveChanges(); 
      return data; 
     } 
    } 
} 

그리고 서비스가 아닌 DataTable 속성에 GetDataToProcess 방법을 사용합니다.

참고 :이 코드는 예제 일 뿐이므로 적절하지 않을 수 있습니다. 단지 해결 방법 일뿐입니다. 또한 null 검사를 마치고 내부적으로 MyDbContext의 인스턴스를 사용할 다른 클래스에 GetDataToProcess을 추출하여 리팩토링해야합니다.

+0

해답을 가져 주셔서 감사합니다. 모든 단일 읽기에 대해 동일한 컨텍스트가 사용 된 경우이 작업이 가능합니다. 그러나 이것이 사실이 아닐 것이라는 상황이 있습니다. 웹 api 및 mvc 응용 프로그램, 웹 팜 등의 다른 프로젝트 – eyeballpaul

+0

예, 단순한 아이디어였습니다. 그런 다음 액세스 확인을 공유 레이어 (즉, 데이터베이스)로 이동해야합니다. –

0

나는 내가 필요한 것일 수있는이 게시물을 발견했습니다. 나는 그것을 더

How can I lock a table on read, using Entity Framework?

으로 볼 필요하지만이 같은 특정 읽기/업데이트에 대한 분리 레벨 변경과 같이 기본적으로는 같습니다

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead })) 
{ 
    var newUrl = dbEntity.URLs.FirstOrDefault(url => url.StatusID == (int) URLStatus.New); 
    if(newUrl != null) 
    { 
     newUrl.StatusID = (int) URLStatus.InProcess; 
     dbEntity.SaveChanges(); 
    } 
    scope.Complete(); 
} 
분명히

등 내 자신의 개체/로직을 사용하여

0

저장 프로 시저가 작업을 수행하는 경로를 결정했습니다.그 이유는 작업 단위/담당자/서비스 계층이 계층화 된 방식으로이 방법을 사용하는 것이 더 논리적이었습니다.

관련 문제