集成测试期间访问另一个线程中的数据库行

时间:2018-09-04 13:52:47

标签: grails gorm integration-testing

从Grails 2.5.6升级后,我在Grails 3.3.8应用程序中遇到问题。

我有一个使用Row.findAll()从H2数据库获取记录的服务。然后,它创建一个闭包列表以供将来执行。然后,列表由ThreadExecutor通过invokeAll()运行。在每个闭包中,我都是通过Row.findById()获取数据的。

当我运行程序时它可以工作,但是在集成测试中不起作用。我检查了Row.findAll().size()在闭包内是否返回0,但恰好在invokeAll()之前返回了正数。

更新:

我为此准备了小型测试:

@Integration
@Rollback
class TestSpec extends Specification {
    void "test something"() {
        when:
            f()
        then:
            g()
    }
    private void f() {
        Raw raw = new Raw()
        raw.text = "text"
        raw.save(flush: true)
    }
    private void g() {
        Closure closure = {
            try {
                def x = rawService.getRawSize()
                if (x != 1) throw new Exception("A: x = " + x)
            } catch (Exception e) {
                e.printStackTrace()
                throw e
            }
        }
        def x = rawService.getRawSize()
        executorService.invokeAll([closure])
    }
}

上面的代码不起作用。它会引发异常。

1 个答案:

答案 0 :(得分:1)

Raw.withNewSession块中包装f()方法的主体。这会将您的新实例保存在单独的会话中。关闭完成后,会话将关闭,并保留您的实例并允许在另一个会话或线程中对其进行访问。

private void f() {
    Raw.withNewSession {
        Raw raw = new Raw()
        raw.text = "text"
        raw.save(flush: true)
    }
}