Доступ к строке базы данных в другом потоке во время интеграционного теста - PullRequest
0 голосов
/ 04 сентября 2018

У меня проблема в приложении Grails 3.3.8 после обновления с Grails 2.5.6.

У меня есть служба, которая использует 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 голосов
/ 10 сентября 2018

Оберните тело вашего метода f() в блок Raw.withNewSession. Это сохранит ваш новый экземпляр в отдельном сеансе. После завершения закрытия сеанс будет закрыт, сохраняя ваш экземпляр и предоставляя доступ к нему в другом сеансе или потоке.

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