grails上的同步块可在Windows上运行,但在linux中不可用

问题描述 投票:0回答:1
我有一个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:

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

      java版本“ 1.7.0_79”
  • Java™SE运行时环境(内部版本1.7.0_79-b15)
  • Java HotSpot(TM)64位服务器VM(内部版本24.79-b02,混合模式)
  • 任何线索?

    谢谢

  • java linux windows grails synchronized
    1个回答
    2
    投票
    您对为什么得到

    StaleObjectStateException的理解是正确的。

    如果您要查找的是悲观锁定(在任何给定时间只允许一个事务访问数据),则可以使用域类

    lock()

    方法:class TestService { static transactional = true TesteSync incrementa() { TesteSync t = TesteSync.lock(1) t.contador++ return t.save() } }
    您可以了解有关Grails悲观锁定here的更多信息。

    PS:默认情况下,Grails服务是事务性的。但是在我的示例中,我明确地使服务成为事务性的,以引起您的注意:Grails自动释放锁定when the transaction commits。我还删除了刷新,因为在事务提交时数据将被刷新。如果您是通过未显式设置为

    @@ Transactional

    的控制器方法执行此操作的,则需要冲洗。提示:通过ID查询时,您可以执行此操作...

    SomeDomainClass.get(1)

    ...代替这个...

    SomeDomainClass.findById(1)

    © www.soinside.com 2019 - 2024. All rights reserved.