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