我正在尝试对 Grails 中服务内的实体执行锁定。
编码:
TheEntity entityForUpdate = TheEntity.lock(entityId)
(...) // some code
entityForUpdate.save()
此代码一直有效,直到发生并发访问。发生这种情况时,一个线程在第一个线程执行代码时保持锁定。一旦锁被释放,就会抛出异常:
ERROR errors.GrailsExceptionResolver - StaleObjectStateException occurred when processing request: [POST] /Portal/Controler/theMethod - parameters:
param1: 18
param2: 86,32
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [core.TheEntity#133]. Stacktrace follows:
Message: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [core.TheEntity#133]
Line | Method
->> 96 | lock in org.hibernate.dialect.lock.SelectLockingStrategy
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1441 | lock in org.hibernate.persister.entity.AbstractEntityPersister
| 110 | upgradeLock . . . . . . . . . . . . . in org.hibernate.event.def.AbstractLockUpgradeEventListener
| 86 | onLock in org.hibernate.event.def.DefaultLockEventListener
| 774 | fireLock . . . . . . . . . . . . . . in org.hibernate.impl.SessionImpl
| 758 | lock in ''
| 665 | doInHibernate . . . . . . . . . . . . in org.springframework.orm.hibernate3.HibernateTemplate$10
| 406 | doExecute in org.springframework.orm.hibernate3.HibernateTemplate
| 374 | executeWithNativeSession . . . . . . in ''
| 663 | lock in ''
| 148 | lock . . . . . . . . . . . . . . . . in
...
我不明白为什么会这样。为什么lock方法会抛出这个异常?
编辑:
我最终选择从实体中删除版本以避免问题:
class TheEntity {
...
static mapping = {
version false
}
...
}
为了获取更新的数据,我还将服务方法的事务模式设置为 READ_COMMITED
@Transactional(isolation=Isolation.READ_COMMITTED)
def theMethod() {
}