2014-04-10 43 views
0

我们有一个grails应用程序,它具有存储在grails数据库中的各种域对象。该应用程序连接到第二个数据库,运行一些原始的SQL,并在一个表中显示结果。它基本上是一个报告服务器grails如何(重新)连接到第二个数据库

我们在DataSource.groovy中如指定数据源第二次向连接需第二DB:

dataSource_target { 
dialect = org.hibernate.dialect.MySQLInnoDBDialect 
pooled = true 
jmxExport = true 
driverClassName = "com.mysql.jdbc.Driver" 
username = "bla" 
password = "bla" 
} 

然后在控制器中,我们有

static mapping = { 
    datasource 'ALL' 
} 

然后在服务上,我们有:

  con = new Sql(dataSource_target) 
     rows = con.rows(sql) 

它的工作原理,但有两个大问题:

  1. 如果在执行grails run-app时,报告应用程序无法连接到第二个“目标”数据源,则无法启动。

  2. 一旦运行,如果应用程序失去与目标数据库的连接,它不会尝试重新连接,则必须再次停止并启动整个grails应用程序。

我们需要一些更强大的 - 目标当用户决定运行报告DB只叫 - 它不是当我们调用CON运行应用程序启动时,并应尝试连接(或重新连接)=新的Sql(数据源)。

任何想法我们如何实现这一目标? IE浏览器。一种在运行时连接到数据库的方式,拉回一些行,并且如果与目标数据库的连接丢失,然后重新建立,下次运行报告时它仍然可以工作。另外,如果应用程序在目标数据库不存在时启动,它仍应该启动,因为它在启动时不依赖于它。

感谢,

回答

2

,可以考虑添加一些额外的属性,以允许它尝试重新连接。例如:

dataSource_target { 
    dialect = org.hibernate.dialect.MySQLInnoDBDialect 
    pooled = true 
    jmxExport = true 
    driverClassName = "com.mysql.jdbc.Driver" 
    username = "bla" 
    password = "bla" 
    properties { 
    maxActive = -1 
    minEvictableIdleTimeMillis=1800000 
    timeBetweenEvictionRunsMillis=1800000 
    numTestsPerEvictionRun=3 
    testOnBorrow=true 
    testWhileIdle=true 
    testOnReturn=true 
    validationQuery="SELECT 1" 
    } 
} 

我建议您改变属性以适合您的需求。但是,这不会解决应用程序启动时数据库不可用的问题。

为避免这种情况,您必须避免使用Grails数据源。在这种情况下,您需要在正在调用数据库的服务中定义数据源。

def db = [ 
    url:'jdbc:hsqldb:mem:testDB', 
    user:'sa', 
    password:'', 
    driver:'org.hsqldb.jdbc.JDBCDriver' 
] 
def sql = Sql.newInstance(db.url, db.user, db.password, db.driver) 

当然,修改此以适合您的需求。你甚至可以从Config.groovy中取出这些设置,而不是硬编码它们(强烈推荐)。

1

要从application.yml动态地获取这些值,我想这取决于哪个版本的Grails 3,因为我知道DSN的配置已经在3.2.8略有变化:

def db = [:] 
def dataSources = Holders.grailsApplication.config.dataSources 
db.user = dataSources.dataSource_otherDsn.username 
db.password = dataSources.dataSource_otherDsn.password 
db.driver = dataSources.dataSource_otherDsn.driverClassName 
if (Environment.current == Environment.DEVELOPMENT) { 
    db.url = Holders.grailsApplication.config.environments.development.dataSources.dataSource_otherDsn.url 
} else if (Environment.current == Environment.PRODUCTION) { 
    db.url = Holders.grailsApplication.config.environments.production.dataSource.dataSource_otherDsn.url 

} 
def sql = Sql.newInstance(db.url, db.user, db.password, db.driver) 

由于配置值被分割在.yml文件的不同段上,我不得不寻找位于不同位置的位。

虽然这是在服务和GrailsApplicationAware与标准的GrailsApplication未能拿起与Holders.grailsApplication工作。尽管直接调用服务是BootStrap,因此可能与启动过程要求有关。

无论如何,它会使它更具动态性。

相关问题