我有一个grails应用程序依赖于同步块到服务。 当我在Windows上运行它时,同步按预期工作,但是当我在ams linux上运行时,得到一个StaleObjectStateExceptionexception。
在下面的例子中重现了这个问题。
class TestService { private final Object $lock = new Object[0]; TesteSync incrementa() { synchronized ($lock) { TesteSync t = TesteSync.findById(1) t.contador++ t.save(flush: true) Thread.sleep(10000) return t } }
}
在我的理解,这种exception发生,因为多个线程正试图保存相同的对象。 这就是为什么我使用同步块。
Linux的Java:
Windows的Java:
任何线索?
谢谢
你是对的,为什么你会得到StaleObjectStateException 。
如果你正在寻找的是悲观锁(在任何给定的时间只允许一个事务访问数据),那么你可以使用域类lock()方法:
class TestService { static transactional = true TesteSync incrementa() { TesteSync t = TesteSync.lock(1) t.contador++ return t.save() } }
您可以在这里了解有关Grails悲观锁定的更多信息。
PS:Grails服务默认是事务性的。 但在我的例子中,我明确地提出了服务事务来调用注意事项: 当事务提交时,锁由Grails自动释放。 我也删除了刷新,因为事务提交时数据被刷新。 如果你是从一个未明确设置为@Transactional的控制器方法来做这件事,那么你需要flush。
提示:当你通过ID查询,你可以做到这一点…
SomeDomainClass.get(1)
而不是这个…
SomeDomainClass.findById(1)
Espero que ajude。