【问题标题】:GORM Integration Tests with 3 or more DataSources具有 3 个或更多数据源的 GORM 集成测试
【发布时间】:2018-07-26 13:41:06
【问题描述】:

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

设置的正确方法是什么?

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

Source Code

环境

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
}

【问题讨论】:

  • 注意:这曾经在 Grails 3.2 中工作,这是在升级到 3.3 后发现的。但是 Github 中提供的示例是一个干净的 3.3.6 项目。

标签: grails groovy grails-orm spock grails-3.3


【解决方案1】:

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”) 方法。

【讨论】:

  • 升级指南包含一个附加参数:blacklistPattern,这原本是为了防止修复。
猜你喜欢
  • 2012-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-22
  • 1970-01-01
  • 2018-11-12
  • 2015-02-10
  • 1970-01-01
相关资源
最近更新 更多