2016-09-13 7 views
1

우리는 동일한 도메인 객체 인 Message를 업데이트하려고 시도하는 여러 작업자 스레드가있는 동시성이 높은 Grails 앱을 사용하지만 static (정적) 트랜잭션을 사용하여 서비스에 구현 된 비관적 잠금 솔루션 잠금 Message.lock(msg.id)은 많은 경우에 HibernateOptimisticLockingFailureException이됩니다.Grails Gorm 정적 잠금 결과는 HibernateOptimisticLockingFailureException이 발생합니다.

Facility.withTransaction { 
     if (resp?.status == 200) { 
     Message msgCopy = Message.lock(msg.id) 
     msgCopy.state = State.SoftDeleted 
     msgCopy.save(flush: true) 
     } 
    } 

어떻게 고정 잠금을 사용하면 HibernateOptimisticLockingFailure이 될 수 있습니까? 내 이해는 정적 잠금 최신 영구 버전을 읽습니다 것입니다. 이 경우 다른 스레드가 삭제 한 경우입니까?

전체 오류 : 나는 생각한다 (예외를 잡기 제외)

[com.cds.healthdock.messaging.Message] with identifier [58653744]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.cds.healthdock.messaging.Message#58653744] at messaging.OutboxService$_pushMessageToPeer_closure8.doCall(OutboxService.groovy:442) at org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:815)

어떤 전략? isDirty()isEmpty()

+0

응답을 200이면 메시지를 항상 softDelete로 설정해야하는 등 Status를 포함한 모든 필드에 대해 동일한 메시지를 업데이트하려고하는 두 개의 스레드를 디자인 관점에서 추가해야합니다. 메시지에 대한 다른 모든 업데이트는 관련성이 없어지고 손실되거나 덮어 쓸 수 있습니다. –

답변

0

다음은이 문제에 대한 우수하고 매우 상세한 article입니다. 난 당신과 똑같은 문제를 겪고 난 트랜잭션

  • 객체를 객체를 얻고 정적 lock() 방법을 통해
  • 업데이 트를 잠급을 시작
    • , 비관적 잠금을 사용하여 그것을 해결
    • 트랜잭션을 커밋하십시오.

    비슷한 일을하고있는 것처럼 보이지만 한편으로는 거래 내에서 거래하고 있는지 여부를 알 수 없습니다

    the pessimistic locking solution implemented in the service (with transactional set to false)

    그러나 반면에 코드는 withTransaction 내에서 실행되는 것처럼 보입니다. 비관적 잠금 방법은 트랜잭션 내에서 실행되어야합니다.

  • +0

    기사 주셔서 감사합니다. 예, withTransaction을 사용하기 때문에 거래입니다. 우리는 트랜잭션 적이 아닌 다른 방법을 가지고 있습니다. –