我正在尝试在事务服务中创建并持久化Foo实例,然后在Foo
实例一直存在后,触发事件以启动对它的异步处理。
我遇到的问题是,当我尝试从事件处理程序中的持久性中检索Foo
实例时,找不到该实例。
我保留Foo
实例的服务方法如下所示:
Foo makeFoo() {
def foo = new Foo(...).save(flush: true, failOnError: true)
notify("FOO_CREATED_EVT", foo.id)
return foo
}
我的事件处理程序存在于单独的事务服务中,如下所示:
@Selector("FOO_CREATED_EVT")
void onFooCreated(Long fooId) {
def foo = Foo.get(fooId) // also tried findById, with the same outcome
assert foo != null // fails
}
我已经在启用了sql日志记录的情况下逐步完成了代码,并验证了Foo
实例在makeFoo()
中成功保留,但当onFooCreated()
尝试检索它时,它总是失败。据我所知,在触发事件之前刷新保存应导致Foo
实例立即保持,但是如果我在onFooCreated中添加延迟:
Thread.sleep(1000)
def foo = Foo.get(fooId)
assert foo != null // succeeds
然后操作成功,所以我只能假设存在竞争条件,因为flush实际上不是同步持久化实例。
我的项目使用Grails 3.2与Hibernate 5和PostgreSQL 9.6。
我显然做错了什么但是异步事件的文档非常稀疏,并且在这个场景中遇到了问题:(
答案 0 :(得分:1)
flush()
可能已执行,但事务尚未提交或关闭,因此数据对另一个线程不可见,因为事务是隔离的,而另一个线程将使用单独的连接。
您需要确保在触发事件之前已提交事务。