我有一个grails应用程序,它依赖于服务中的同步块。当我在Windows上运行它时,同步可以按预期工作,但是当我在ams linux上运行时,会收到StaleObjectStateException。
在下面的示例中重现该问题。
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 } }
}
据我了解,发生此异常是因为多个线程正在尝试保存同一对象。这就是为什么我使用同步块。
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 的控制器方法执行此操作的,则需要进行刷新。
提示:通过ID查询时,您可以执行此操作…
SomeDomainClass.get(1)
而不是这个
SomeDomainClass.findById(1)