2009-05-28 7 views
2

SqlDataReader를 사용할 때 ExecuteReader 단계에서 완전히 결정한 반환 값 집합입니까? 아니면 읽는 동안 원본 테이블에 기록하여 얻은 결과에 영향을 줄 수 있습니까? 다음은 매우 거친 의사 코드의 예입니다.SqlDataReader - 캐시 된 결과 집합?

sc = new SqlCommand("select * from people order by last, first",db) ; 
sdr = sc.ExecuteReader() ; 

while (sdr.read()) 
{ 
    l = (string) sdr["last"] ; 
    k = (string) sdr["key"] ; 
    if (l.Equals("Adams")) 
    { 
     sc2 = new SqlCommand("update people set last = @nm where key = @key") ; 
     sc2.Parameters.Add(new SqlParameter("@nm", "Ziegler")); 
     sc2.Parameters.Add(new SqlParameter("@key", k)); 
     sc2.ExecuteNonQuery() ; 
    } 
} 

난 당신이 읽고있는 테이블에 서면으로 인한 다른 환경에서 잘못된 오류를 많이 봤어요. 여기서 레코드 k는 목록의 상단 (아담스)에서 하단 (지글러)까지 부딪힌다. 저는 SqlDataReader가 면역 적이라고 가정했습니다 (하!). 참된? 그릇된?

답변

4

transaction isolation level 또는 다른 잠금 힌트에 따라 다르지만 기본적으로 SQL Server의 테이블에서 iirc가 해당 레코드를 잠그므로 게시 한 코드가 교착 상태가되거나 (결국 sc2가 시간 초과 됨) 업데이트가 트랜잭션 로그 및 없음은 독자가 완료 될 때까지 기록됩니다. 나는 내 머리 꼭대기에서 어느 것을 기억하지 못한다.

+0

실제 구현은 제대로 작동하는 것처럼 잘 작동합니다. 테이블이 잠기지 않도록 확실히 레코드를 업데이트했지만 정렬 순서에 영향을 줄 수있는 필드는 변경하지 않았습니다. – SeaDrive

+0

2 번과 비슷한 소리가납니다. 트랜잭션 로그에 보관되는 위치를 업데이트합니다. 그것 또는 당신은 어딘가 약한 격리 수준을 설정하고 있습니다. –

1

내가 보는 한 가지 문제는 독자가 열리면 데이터베이스 연결을 소유하므로 읽는 사람이 열려있는 동안 다른 사람이 사용할 수 없다는 것입니다. 따라서 가능한 다른 방법은 다른 데이터베이스 연결을 사용하는 것입니다. 트랜잭션 수준에 따라 달라집니다.

+0

별도의 데이터베이스 연결을 사용했습니다. – SeaDrive

0

이러한 업데이트로 인해 읽기 데이터가 변경되지 않는다고 가정하려면 데이터를 임시 개체 컨테이너, 그리고 모든 읽기가 완료되면 다음 업데이 트합니까? 문제를 논증으로 만들 것입니다.

물론이 질문은 "이게 실제로 작동하는 방식"의 관점에서 흥미로운 질문을 찾았습니다.

0

쿼리 결과를 반복하는 동안 업데이트를 수행하려는 경우이 모든 내용을 데이터 집합으로 읽을 수 있습니다.

당신이 이것에 대해 묻지 않았다는 것을 알고 있고 이것은 또한 의사 코드라는 것을 알고 있지만 using() 문에서 sc, sdr 및 sc2 변수를 감싸서 제대로 폐기되었는지 확인하십시오.