繁体   English   中英

grails 上的同步块适用于 Windows,但不适用于 linux

[英]synchronized block on grails works on windows but no in linux

我有一个依赖同步块进入服务的 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版本“1.7.0_85”
  • OpenJDK 运行时环境 (amzn-2.6.1.3.61.amzn1-x86_64 u85-b01)
  • OpenJDK 64 位服务器 VM(构建 24.85-b03,混合模式)

视窗Java:

  • java版本“1.7.0_79”
  • Java(TM) SE 运行时环境(构建 1.7.0_79-b15)
  • Java HotSpot(TM) 64 位服务器 VM(构建 24.79-b02,混合模式)

有什么线索吗?

谢谢

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM