Grails上的同步块在Windows上工作,但在Linux中没有

我有一个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:

  • java版本“1.7.0_85”
  • OpenJDK运行时环境(amzn-2.6.1.3.61.amzn1-x86_64 u85-b01)
  • OpenJDK 64位服务器虚拟机(内置24.85-b03,混合模式)

Windows的Java:

  • java版本“1.7.0_79”
  • Java(TM)SE运行时环境(build 1.7.0_79-b15)
  • Java HotSpot(TM)64位服务器虚拟机(构build24.79-b02,混合模式)

任何线索?

谢谢

Solutions Collecting From Web of "Grails上的同步块在Windows上工作,但在Linux中没有"

你是对的,为什么你会得到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。