2009-03-06 6 views
1

PreparedStatement을 사용하여 MS SQL 데이터베이스에서 데이터의 하위 집합을 선택합니다. 결과 집합을 반복하면서 행을 업데이트하려고합니다. 순간 나는이 같은 것을 사용 :preparedStatement select를 사용하여 데이터베이스 업데이트 선택

prepStatement = con.prepareStatement(
        selectQuery, 
        ResultSet.TYPE_FORWARD_ONLY, 
        ResultSet.CONCUR_UPDATABLE); 


rs = prepStatement.executeQuery(); 

while(rs.next){ 
rs.updateInt("number", 20) 
rs.updateRow(); 
} 

데이터베이스가 올바른 값으로 업데이트,하지만 다음과 같은 예외 얻을 수있다 :

Optimistic concurrency check failed. The row was modified outside of this cursor. 

내가 봤했습니다,하지만되지 않았습니다 문제에 대한 도움을 찾을 수 있습니다.

이 예외를 어떻게 방지합니까? 아니면 프로그램에서 내가 원하는 것을 수행했기 때문에 무시할 수 있습니까?

+0

어떤 트랜잭션 격리 수준이 사용되고 있는지 알려줄 수 있습니까? – ordnungswidrig

+0

... 정확한 쿼리와 정확히 일치하는 열은 무엇입니까? – vladr

답변

2

레코드가 데이터베이스에서 (커서를 통해) 검색된 시점과 다시 저장하려고 시도한 시점 사이에 레코드가 수정되었습니다. number 열이 안전하게 독립적으로 독립적으로 다른 프로세스가 이미 다른 값으로 number 열을 설정하는 데, 당신은 어떻게 유혹 할 수있는 기록 또는의 나머지를 업데이트 할 수있는 경우 그러나

con.execute("update table set number = 20 where id=" & rs("id")) 

, 경쟁 상태가 계속 발생하면, 변경 내용이 다른 프로세스에서 덮어 쓸 수 있습니다. 예외가 (레코드가 갱신되지 않은), 후 실패 레코드를 통해 두 번째 패스 할 가능성 (메모리) 큐에 실패 레코드를 추진 (재평가 무시

최선의 전략은 query의 조건과 적절하게 업데이트 - query의 조건 중 하나로 number <> 20을 추가하십시오. 더 이상 레코드가 실패하지 않을 때까지 반복하십시오. 결국 모든 레코드가 업데이트됩니다. 당신은 업데이트 할 행을 정확히 알고 가정

+0

사실, 예외가 있음에도 불구하고 레코드가 업데이트되었습니다. –

+0

귀하의 측면에서 optimisitic 잠금 예외를 트리거하는 "다른 사람"이 실제로보고있는 업데이트를 수행 했습니까? :) – vladr

+0

아니요 업데이트는 한 곳에서만 발생하며 내 프로세스는 데이터베이스에 액세스하는 유일한 사람입니다 –

0

, 나는 당신의 AUTOCOMMIT

  • SET 할 것 OFF로
  • 테이블에서 SERIALIZABLE
  • SELECT ROW1, ROW1에
  • SET 격리 수준 WHERE UPDATE
  • 에 대한 somecondition
  • UPDATE 행
  • 는 COMMIT

이것은 비관적 인 잠금을 통해 성취됩니다 (DB에서 행 잠금이 지원된다고 가정하면 작동합니다)

관련 문제