【问题标题】:Grails with commons-dbcp2 connection pool datasource带有 commons-dbcp2 连接池数据源的 Grails
【发布时间】:2014-10-28 22:08:10
【问题描述】:

背景:我有 2 个项目

A:基于 Spring 的 java 项目

B:用于 gui 的 Grails 项目

我有两个相关的问题:

  1. 如何在 grails 项目中使用 org.apache.commons.dbcp2.BasicDataSource 而不是默认的 apache tomcat DataSource? org.apache.tomcat.jdbc.pool.DataSource 有一个限制,它只允许一个 initSql String。我想运行 2 个 init sql 语句 ["SET SCHEMA", "SET ROLE"],这可以通过 dbcp2 实现,因为它需要一个 connectionInitSqls List。我还尝试将 2 条 sql 语句与分号组合,但 tomcat 数据源给出了验证错误。

  2. 是否可以从另一个父 bean 扩展数据源?我想从我的 java 项目中定义的抽象 bean 扩展 grails 数据源,想法是重用通用数据源属性。

【问题讨论】:

    标签: grails apache-commons-dbcp


    【解决方案1】:

    我还没有看到这个特定池和 Tomcat 池之间的性能比较,但我猜你会用一辆只播放一个广播电台的法拉利换一辆播放两个电台的老爷车。 Look at the comparisons of Tomcat vs the others - it's significantly faster。如果您没有获得太多流量,那么也许这没什么大不了的。

    抛开性能问题不谈,注册你自己的DataSource 很容易——只需在grails-app/conf/spring/resources.groovy 中创建一个具有正确名称的bean,你的bean 就会覆盖Grails 配置的那个。所有 Spring bean 都是如此;如果您使用 Grails 或插件之前配置的名称注册一个新 bean,那么您的将获胜。并根据需要设置属性:

    import org.apache.commons.dbcp2.BasicDataSource
    
    beans = {
    
       dataSource(BasicDataSource) {
          url = '${dataSource.url}'
          driverClassName = '${dataSource.driverClassName}'
          username = '${dataSource.username}'
          password = '${dataSource.password}'
          // other valid setters - see the source or
          // javadocs for what's available
       }
    }
    

    请注意,在引用 Config.groovy 变量时必须使用单引号(DataSource.groovy 中的值会合并到“dataSource”键下的主配置中),因为该触发器的 Spring 属性占位符处理将替换指定的在系统属性、属性文件和 Grails 中的配置中查找的键。如果你使用双引号,它们会变成 GString 并且过早地被评估并且会导致异常。

    但这还不够——除了大幅降低池性能之外,这将为您提供一个有效的连接池,但会消除 Grails 添加的两个很酷的功能。如果你不定制任何东西,你得到的dataSource bean 实际上是两个代理包装真正的dataSource。一个是org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy,它避免了在没有更新发生时在事务开始时配置连接的成本。它配置了一个缓存方法调用的Connection 代理(setAutoCommit(false),设置隔离级别、只读、超时等),当您进行实际更新时,它将这些值应用于实际连接并使用它。但是,如果您不进行任何更新,您将节省时间,虽然节省的时间不多,但会在繁忙的网站上加起来。另一个是org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy,它确保在事务或休眠会话期间,如果您转到dataSource 获取连接,您将获得已经使用的连接,因此您将能够看到活动更新,读取未提交的更改等。

    所以实际上有 3 个数据源 bean,您可以使用名称 dataSourceUnproxied 注册上面的一个,其他通过引用注册:

    dataSourceUnproxied(BasicDataSource) {
       url = ...
       ...
    }
    dataSourceLazy(LazyConnectionDataSourceProxy, ref('dataSourceUnproxied'))
    dataSource(TransactionAwareDataSourceProxy, ref('dataSourceLazy'))
    


    即使相关,您也应该对每个问题提出一个问题。我将用指向代码的指针来回答第二个问题。如果有多个数据源,并且每个数据源有 3 个 bean,那么您最终会得到大量冗余代码和配置,因此 DataSourceGrailsPlugin 确实创建了一个具有公共属性的抽象父 bean 定义并从中构建真正的 bean;你可以看到这一切in the code

    【讨论】:

    • 非常感谢,感谢您的帮助!
    猜你喜欢
    • 2016-05-02
    • 1970-01-01
    • 2013-09-04
    • 1970-01-01
    • 2019-12-02
    • 2016-12-05
    • 2017-03-13
    • 2018-12-28
    • 1970-01-01
    相关资源
    最近更新 更多