我目前有一些Grails应用程序使用单个MongoDB副本集来处理某些共享信息。最近,一场比赛条件可再现地发生在:
没有使用flush调用save:true,但是第一个资源save在第二个资源保存之前发生了两行,而其间的行是对第二个资源的更改。冲洗可能会解决这个问题,但我想实施一个解决方案,以保证不再出现具体情况。
我对解决方案的一些天真/第一推力实施涉及到& amp;发布信号量方法:
public synchronized boolean releaseSemaphore(Thing thing){
if(thing.semaphore==true){
thing.semaphore=false
if(thing.save(failOnError:true, flush:true)){
return true
}
else{
log.warn "releasing thing semaphore, thing: "+thing.id+", failed on thing.save()"
return false
}
}
else{
log.error "releaseThingSemaphore called with thing: "+thing.id+" when semaphore not held."
return false
}
}
public synchronized getThingWithSemaphore(String thingId){
def thing = Thing.get(thingId)
if(thing){
if(thing.semaphore==false){
thing.semaphore=true
if(thing.save(failOnError:true, flush:true)){
return [thing, true]
}
else{
log.debug "Failed to get lock on thing: "+thingId
return [null, false]
}
}
else{
log.warn "Thing: "+thingId+" was locked when getThingWithSemaphore was called"
return [null, false]
}
}
else{
return [null, false]
}
}
GORM API的Thing.lock(thingId){(http://grails.github.io/grails-doc/3.0.x/guide/GORM.html#locking).lock()}是否会完成我在上面的实现中尝试实现的相同保证(在写入之前获取信号量时)阅读重大行动)?
http://www.anyware.co.uk/2005/2012/11/12/the-false-optimism-of-gorm-and-hibernate/(虽然我意识到它的旧)声称.lock()方法用于在事务外部静默失败,而不是实际锁定任何东西。这仍然是这样吗?
(我也担心MongoDB对事务的一般支持级别,以及这对GORM .lock()调用的影响)
如果我要在需要跨应用程序实例锁定的不同数据中心部署相同应用程序的多个实例(或交叉不同的应用程序共享相同的MongoDB复制集数据源),我是否能够利用GORM API启用跨应用程序文档锁定?