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:

Windows java:

有什么线索吗?

谢谢

关于为什么会收到 StaleObjectStateException

你是对的

如果您正在寻找的是悲观锁定(在任何给定时间只允许一个事务访问数据),那么您可以使用域 class 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)