문제

우리는 엄청난 선택 명령문이있는 SQL Server 2005 데이터베이스 (행 버전 없음)를 사용하고 있으며, 실행에서 다른 문장을 차단하는 것을보고 있습니다 ( sp_who2). 선택한 진술이 차단을 일으킬 수 있다는 것을 몰랐습니다. 이것을 완화하기 위해 할 수있는 일이 있습니까?

도움이 되었습니까?

해결책

CAN 블록 업데이트를 선택합니다. 적절하게 설계된 데이터 모델과 쿼리는 최소한의 차단 만 유발하며 문제가되지 않습니다. Nolock 힌트가있는 '평소'는 거의 항상 잘못된 대답입니다. 적절한 대답은 쿼리를 조정하여 거대한 테이블을 스캔하지 않도록하는 것입니다.

쿼리가 조율되지 않으면 먼저 고려해야합니다. 스냅 샷 격리 레벨, 두 번째로 사용을 고려해야합니다 데이터베이스 스냅 샷 마지막 옵션은 더러운 읽기 여야합니다 (그리고 변경하는 것이 좋습니다. 격리 수준 놀락 힌트를 사용하는 대신). 이름에서 명확하게 말하면 Dirty Read는 일관성이없는 데이터를 반환합니다 (예 : 총 시트는 불균형 일 수 있음).

다른 팁

에서 선적 서류 비치:

Shared (S) 잠금 장치는 동시 트랜잭션을 읽을 수 있도록합니다 (SELECT) 비관적 동시성 통제하에있는 자원. 자세한 내용은 참조하십시오 Types of Concurrency Control. 다른 트랜잭션은 데이터를 수정할 수 없습니다 shared (S) 자원에 자물쇠가 있습니다. Shared (S) 트랜잭션 격리 레벨이 반복 가능한 읽기 또는 더 높은 것으로 설정되거나 잠금 힌트가 사용되지 않는 한 자원의 잠금은 읽기 작업이 완료 되 자마자 릴리스됩니다. shared (S) 거래 기간 동안 잠금.

shared lock 다른 공유 잠금 장치 또는 업데이트 잠금 장치와 호환되지만 Exlibor Lock은 아닙니다.

그것은 당신을 의미합니다 SELECT 쿼리가 차단됩니다 UPDATE 그리고 INSERT 쿼리 및 그 반대도 마찬가지입니다.

SELECT 쿼리는 테이블에서 값 블록을 읽을 때 임시 공유 잠금 장치를 배치하고 읽을 때 제거합니다.

잠금이 존재하는 경우 잠긴 영역의 데이터로 아무것도 할 수 없습니다.

SELECT 쿼리는 서로를 차단하지 않습니다 (그렇지 않은 한 SELECT FOR UPDATE)

당신은 활성화 할 수 있습니다 SNAPSHOT 데이터베이스에서 격리 레벨을 사용하여 사용하지만 방지하지는 않습니다. UPDATE 쿼리가 잠겨있는 쿼리 SELECT 쿼리 (귀하의 경우 인 것 같습니다).

그러나 그것은 예방할 것입니다 SELECT 쿼리가 잠겨있는 쿼리 UPDATE.

또한 주목하십시오 SQL Server,와 달리 Oracle, 잠금 관리자를 사용하여 메모리 내 링크 된 목록에 잠금을 유지합니다.

즉, 무거운 하중에서 링크 된 목록 자체가 트랜잭션 스레드에 의해 잠겨 있어야하기 때문에 잠금을 배치하고 제거하는 것만으로도 속도가 느려질 수 있습니다.

더러운 읽기를 수행하려면 다음 중 하나를 수행 할 수 있습니다.

 using (new TransactionScope(TransactionScopeOption.Required, 
 new TransactionOptions { 
 IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }))
 {
 //Your code here
 }

또는

SelectCommand = "SELECT * FROM Table1 WITH (NOLOCK) INNER JOIN Table2 WITH (NOLOCK) ..."

더러운 읽기를 원하는 모든 테이블 후에 (Nolock)와 함께 써야한다는 것을 기억하십시오.

당신은 설정할 수 있습니다 거래 수준 커밋되지 않은 것을 읽습니다

교착 상태를 얻을 수도 있습니다.

"하나의 테이블 만 포함 된 교착 상태"http://sqlblog.com/blogs/alexander_kuznetsov/archive/2009/01/01/reproducing-deadlocks-involving-on-on-table.aspx

또는 잘못된 결과 :

"읽기에 따라 선택하고 반복 가능한 읽기에서 선택하면 잘못된 결과를 반환 할 수 있습니다."

http://www2.sqlblog.com/blogs/alexander_kuznetsov/archive/2009/04/10/selects-under-bund-led-committed-and-repeatable-may-return-incorrect-results.aspx

당신이 사용할 수있는 WITH(READPAST) 테이블 힌트. 그것은 그것과 다릅니다 WITH(NOLOCK). 트랜잭션이 시작되기 전에 데이터를 얻을 수 있으며 아무도 차단하지 않습니다. 거래가 시작되기 전에 성명서를 실행했다고 상상해보십시오.

SELECT * FROM table1  WITH (READPAST)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top