2009-11-09 4 views
2

몇 가지 windwos 서비스가 있습니다. SQL Server에서 xml 열을 조작하고 업데이트합니다.xml SQL Server의 열 업데이트 및 잠금

서비스 A-는 XML
서비스 B-는 XML을
서비스 A- 업데이트 XML (이 손실됩니다)
서비스 B- 업데이트 XML을 가져옵니다 가져옵니다

내가 행을 잠 가야하고 내가 다음 코드를 사용 :

SqlCommand cmdUpdate = new SqlCommand(); 
      cmdUpdate.CommandText = "select MyXML from MyTable with(holdlock,rowlock) where [email protected]"; 
      cmdUpdate.Parameters.AddWithValue("@id", id); 

     using (SqlConnection conn = Helper.GetConnection()) 
     { 
      cmdUpdate.Connection = conn; 
      SqlTransaction ts = conn.BeginTransaction(); 
      cmdUpdate.Transaction = ts; 
      XElement elem = XElement.Parse(cmdUpdate.ExecuteScalar().ToString()); 
      UpdateXElement(elem); 
      cmdUpdate.Parameters.Clear(); 
      cmdUpdate.CommandText = "update MyTable set [email protected] where [email protected]"; 
      cmdUpdate.Parameters.AddWithValue("@id", id); 
      cmdUpdate.Parameters.AddWithValue("@xml", elem.ToString()); 

      cmdUpdate.ExecuteNonQuery(); 
      ts.Commit(); 
     } 
    }` 

그러면 교착 상태가 발생합니다.

이 문제를 해결하기 위해 더 좋은 아이디어가 있습니까?

감사합니다.

답변

0

설명하는 시나리오는 교착 상태가 아닙니다. 그것은 즉, 잠금 경합의, 잠금 장치가 정확히 무엇을 :

  1. 서비스 A- XML ​​- Service A locks XML
  2. 서비스 B-는 XML을 가져옵니다 가져옵니다 이
  3. 서비스 A- 업데이트 XML (이 손실됩니다
  4. - Services B places lock request which waits for service A to release the lock) - Service A should commit or rollback the transaction to release the lock.
  5. 서비스 B- 업데이트 XML - Service B acquires the lock on the XML and updates it

Service B이 단계 사이에 고정됩니다 23.

이것은 가능한 빨리 이러한 단계를 수행해야 함을 의미합니다.

업데이트 :

당신은 트랜잭션에서 행을 고정하는 HOLDLOCK를 사용합니다.

HOLDLOCK은 다른 공유 잠금과 호환되지만 업데이트 잠금이 적용되지 않는 공유 잠금은 UPDATE입니다.

여기 무슨 일이야 :와 호환되지 않습니다

  1. Service A 장소 row 1의 업데이트 잠금을 배치 row 1
  2. Service A 시도에 row 1
    • Service B 장소 공유 잠금 공유 잠금 공유 잠금은 에 의해 2 단계에 배치됩니다. Service A은 대기 상태로 들어갑니다 (1 단계에있는 공유 잠금을 계속 누르고 있음).
    • Service BService A에 의해 배치 된 공유 잠금과 호환되지 않는 row 1에 업데이트 잠금을 넣으려고합니다 (1). Service B은 대기 상태가됩니다. DEADLOCK.

여기 SELECT 절에 공유 잠금을 배치 아무 소용이 없습니다. 대신 절에 UPDLOCK을 입력해야합니다. 이렇게하면 트랜잭션 잠금이 완전히 호환되지 않게되고 트랜잭션은 잠금을 획득하기 전에 다른 트랜잭션이 완료 될 때까지 대기해야합니다.

이 시나리오에서는 교착 상태가 불가능합니다.

+0

예,하지만 때때로 발생합니다 "트랜잭션 (프로세스 ID 108)이 다른 프로세스에서 잠금 리소스에 교착 상태가 발생하여 교착 상태가 발생했습니다. 트랜잭션을 다시 실행하십시오." 예외. 내 코드가 책임 져야합니까 (잠금으로 인해)? 이 시나리오에서 교착 상태를 방지하는 방법은 무엇입니까? 감사합니다. –

+0

고마워요. Updlock이 문제를 해결했습니다! 감사합니다. –