2011-09-11 3 views
3

때때로 데이터베이스 교착 상태가 발생하는 WCF 서비스가 있습니다. 내 서비스는 협의회에 신청서를 제출할 수있게하며 협의회가 협의회를 업데이트 할 수 있기 때문에 다시 협의 할 수 있습니다. 각 응용 프로그램에는 여러 개의 문서가 연관되어 있습니다. 느린 쿼리로 교착 상태를 피할 수있는 방법

그래서

이 같은 이벤트 집합 내 서비스에 난 이유는 2 부에서 문서가에서 SQL 서버에 제출하는 데 시간이 소요 믿습니다 제 3 부에서

1) Application #1 is submitted 
2) A document is uploaded for application #1 
3) Application #1 is loaded 
4) Part 2 above finishes 

교착 상태가 발생하는 경우 WCF 서비스를 실행하고이 시간 동안 테이블을 잠급니다.

데이터베이스 응용 프로그램 # 1과 관련 문서를로드하면 문제가 발생합니다.

저는 엔터티 프레임 워크를 사용하고 있습니다. 이 문제를 어떻게 해결할 수 있습니까? 제가 정말로하고 싶은 것은 완전히 제출 된이 상황에서 문서를 적재하는 것입니다. 이것이 내가 무엇입니까 특정 오류입니다 그런데

,

UPDATE
Message: Transaction (Process ID 93) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. 

: 내가 작업의 순서를 변경할 수있는 코멘트 몇 있었다. 파트 2와 파트 3이 WCF 서비스에 대한 서로 다른 호출에 있기 때문에 실제로는 그렇게 할 수 없습니다. 따라서 작업을 주문하는 것은 서비스 사용자가 결정합니다. '당신이 바꾸라고해라.'라고 말하지만, 그렇게 간단하지는 않습니다. 작업의 순서는 최종 사용자가 적절한 순간에 브라우저를 '새로 고'하는 일에 실제로 달려 있습니다.

업데이트 # 2 :이 문제를 재현하는 방법에 대한 조언이 필요합니다. 테스트 애플리케이션을 작성했고 위 파트 2는 파트 3에서 작업을 차단하지만, 결과는 작업 2가 완료되고 작업 3이 완료 될 때까지 작업 3이 막 차단된다는 것입니다.

그래서 파트 3은 보통 3 분이 아니라 1 분 50 초가 소요됩니다. 왜 그것이 나를 위해 차단되고 교착 상태가 발생하지 않는지에 대한 아이디어가 있습니까? 해당 서버에서 전체적으로 데이터베이스 트래픽의 양과 관련이 있습니까? 아니면 테스트 서버를 사용하고 있거나 데이터베이스 설정에 영향을 줄 수 있습니까?

1) 만 트랜잭션의 끝에서 saveChanges() 전화 함께 모든 쿼리를 실행 :

답변

1

일반적으로 죽은 잠금을 피하기 위해 여러 가지 방법 (SQL Server 및 기타 데이터베이스)가 있습니다.

2) 데이터베이스 업데이트를 수행하려면 먼저 모든 읽기 (SELECT)를 수행하고 마지막으로 모든 업데이트를 수행하십시오.

3) 트랜잭션에서 수정되지 않는 데이터 트랜잭션의 판독 값을 수행하십시오.

4) 트랜잭션의 격리 수준을 SERIALIZABLE (성능이 좋지 않음)으로 변경하거나 SNAPSHOT 또는 응용 프로그램 논리가 허용하는 경우 잠금이 설정되지 않은 다른 중간 수준 (예 : READ UNCOMMITTED)으로 변경하십시오.

5) lock(lock_object)을 사용하여 동기화 된 코드 블록을 작성하여 두 스레드가 동일한 트랜잭션을 병렬로 수행하거나 자체 잠금을 수행하는 두 개의 다른 트랜잭션을 수행하지 않도록하십시오.

+0

나는이 질문을 업데이트했다. 나는 그 작전의 순서를 정말로 통제 할 수 없다. 내 해결책은 파트 4 또는 파트 5와 관련이 있습니다. Part 5는 한 번에 여러 개의 스레드가 실행될 수 있기 때문에 좀처럼 들리지 않는다. – peter

+0

여러 개의 스레드가 실행될 수 있지만 데드 록으로 이어지는 작업을 수행하는 코드 부분 만 동기화하면됩니다. 이렇게하면 전체 처리량이 줄어들지 만 다른 옵션은 격리 수준을 변경하여 잠금을 방지하는 것입니다. SNAPSHOT 격리 수준, SQL Server 2005의 새로운 기능으로 데드락 (dead-lock) 문제 해결 데이터를 변경할 때 잠금을 만드는 대신 다른 버전의 데이터를 저장하고 각 트랜잭션은 필요한 데이터의 버전을 읽습니다. –

+0

처음 이었기 때문에 답을 쳤습니다. 나는 문제가 약간 완화 될 수 있다고 생각한다. 교착 상태의 원인이 된 쿼리는 필요하지 않은 데이터베이스 (blob)에서 필드를 가져 오는 것입니다. 즉, 쿼리에서 해당 필드를 제거하면 쿼리가 더 빨라지고 테이블이 잠길 때 발생할 가능성이 줄어 듭니다. 실제 문제를 파악하는 것은 차단을 야기 할 수 있다고 생각하고 있기 때문에 더 어려울 것입니다. 그러나 실제로 교착 상태를 일으키는 것을 해결하기 위해서는 좀 더 복잡해집니다. – peter

1

솔루션의 몇 가지 : 당신은 잠재적으로 커밋되지 않은 행 3 단계 (이 상황에 따라 다름)에 표시 가진 괜찮다면

  • 가 READ UNCOMMITTED의 격리 수준을 사용합니다. 보다 효율적이고 수 있도록 여러분의 EF 컨텍스트에

또는

  • 일괄 변경해야합니다 그들은 (당신의 코드를 보지 않고 당신이이 일을하거나하지 여부를 잘 모르겠어요)
  • 모두 한 번에 실행

편집

아래의 링크는 문제 해결에 도움이 될 당신의 문제를 해결 할 수 있습니다

http://blogs.msdn.com/b/bartd/archive/2006/09/09/deadlock-troubleshooting_2c00_-part-1.aspx

+0

작업 순서를 제어 할 수 없습니다. 내 질문을 업데이트했습니다. 내 솔루션은 내가 생각하는 고립 수준과 관련이 있습니다. – peter

관련 문제