0

当您尝试与超过 2 个数据源交互时,我的集成测试MultipleDbsITSpec失败并出现错误“org.hibernate.HibernateException: No Session found for current thread” 。运行应用程序时不会出现此问题,请参阅BootStrap.groovy

在此处输入图像描述

设置它的正确方法是什么?

我想避免我发现需要用withNewTransaction闭包包装 GORM 查询的解决方法。这会破坏代码的可读性。

源代码

环境

host:TestingMultDbs user$ ./grailsw -version
| Grails Version: 3.3.6
| Groovy Version: 2.4.7
| JVM Version: 1.8.0_181

数据库配置

    development:
    dataSource:
        dbCreate: create-drop
        url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
        logSql: true
    dataSources:
        db2:
          dbCreate: create-drop
          url: jdbc:h2:mem:devDb2;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
        db3:
          dbCreate: create-drop
          url: jdbc:h2:mem:devDb3;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
test:
    dataSource:
        dbCreate: create-drop
        url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
        logSql: true
    dataSources:
        db2:
          dbCreate: create-drop
          url: jdbc:h2:mem:devDb2;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
        db3:
          dbCreate: create-drop
          url: jdbc:h2:mem:devDb3;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE

失败的测试

// Can only declare 1 @Transactional
//    @Transactional("db2") -- causes db3 to fail
//    @Transactional("db3") -- causes db2 to fail
//    @Transactional(["db2","db3"]) -- doesn't exist
@Transactional
void "Test interaction with all 3 databases"() {
    given:
    new DefaultDb(f1: "test").save()
    new Db2Example(f1: "test").save()
    new Db3Example(f1: "test").save()

    when:
    def value1 = DefaultDb.findByF1("test")
    def value2 = Db2Example.findByF1("test")
    def value3 = Db3Example.findByF1("test")

    then:
    value1
    value2
    value3
}

通过测试

void "Test default db"() {
    given:
    new DefaultDb(f1: "test").save()

    when:
    def value = DefaultDb.findByF1("test")

    then:
    value
}

@Transactional("db2")
void "Test default db2"() {
    given:
    new Db2Example(f1: "test").save()

    when:
    def value = Db2Example.findByF1("test")

    then:
    value
}

@Transactional("db3")
void "Test default db3"() {
    given:
    new Db3Example(f1: "test").save()

    when:
    def value = Db3Example.findByF1("test")

    then:
    value
}
4

1 回答 1

0

zyro23在这里解释解决方案: https ://github.com/grails/grails-core/issues/10383

检查更改注册。ChainedTransactionManagerPostProcessor(自 3.3.0 起默认禁用):http ://docs.grails.org/3.3.0/guide/upgrading.html 并尝试通过application.yml重新启用..

grails:
  transaction:
    chainedTransactionManagerPostProcessor:
      enabled: true

使用该配置,省略连接属性应该可以工作(或者说没有区别)。

但请确保您了解链式事务处理的含义,即尽力而为的两阶段提交(“be2pc”)方法。

于 2018-07-26T14:43:48.117 回答