我试图在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() {
}