Grails 异步事件处理程序无法从持久性中检索域实例
Grails async Event handler fails to retrieve domain instance from persistence
我正在尝试在事务服务中创建并保留一个 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 结合使用。
我显然做错了什么,但是关于异步事件的文档非常少,并且在解决这种情况时遇到了困难:(
flush()
可能已执行,但事务尚未提交或关闭,因此数据对另一个线程不可见,因为事务是隔离的,另一个线程将使用单独的连接。
您需要确保在触发事件之前事务已提交。
我正在尝试在事务服务中创建并保留一个 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 结合使用。
我显然做错了什么,但是关于异步事件的文档非常少,并且在解决这种情况时遇到了困难:(
flush()
可能已执行,但事务尚未提交或关闭,因此数据对另一个线程不可见,因为事务是隔离的,另一个线程将使用单独的连接。
您需要确保在触发事件之前事务已提交。