我们正在使用Grails 2.0.4,GORM和Hibernate构建应用程序。当数据库不可用时,Grails将不会初始化,并且启动失败。我们认为我们的池设置可以防止启动失败,但似乎并非如此。
如果池设置不能单独解决这个问题,有没有可能赶上异常resources.groovy
其中,如果数据库服务不能被初始化,切换到临时基于文件的服务?像这样......
resources.groovy
try{
myDataService(PostgresDatabaseServiceImpl){}
}catch(Exception e){
//if database connect failed, use local service instead
myDataService(FileBasedServiceImpl){}
}
即使上述情况可能,也会产生新问题;一旦数据库 可用,如何动态切换回来。我们尝试了上面的try / catch,但没有任何影响,启动问题仍然存在:
创建名为'transactionManagerPostProcessor'的bean时出错: bean的初始化失败
如果有可能通过池设置避免单独启动失败,我们当然可以管理在运行SQL异常当应用程序试图使用不正确的数据库连接,但启动失败,我们无法管理。
DataSource.groovy(游泳池设置)
dataSource {
pooled = true
driverClassName = "org.postgresql.Driver"
properties {
maxActive = 20
minEvictableIdleTimeMillis=1800000
timeBetweenEvictionRunsMillis=1800000
numTestsPerEvictionRun=3
testOnBorrow=true
testWhileIdle=true
testOnReturn=true
validationQuery="SELECT 1"
}
}
hibernate {
cache.use_second_level_cache = false
cache.use_query_cache = false
cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
}
答案 0 :(得分:2)
我们尝试了上面的try / catch,但它没有任何影响,启动问题仍然存在:
所以看来你已经有了一个问题的答案:是否可以在resources.groovy
中为(可能)不可用的数据库注册一个Spring bean。
作为替代方法,您可以尝试在运行时为数据库注册Spring bean。这种方法的优点是,即使注册bean失败,您也可以捕获错误并使用基于文件的服务。如何在运行时注册DataSource bean的示例是show here。
要使用此方法,请在resources.groovy
myDataService(FileBasedServiceImpl)
然后当您需要访问数据源时:
class DataSourceService implements ApplicationContextAware {
def myDataService
ApplicationContext applicationContext
private static PG_BEAN = 'postgres'
def getDataSource() {
try {
getPostgresService()
} catch (ex) {
myDataService
}
}
private getPostgresService() {
def postgres
if (applicationContext.containsBean(PG_BEAN)) {
postgres = applicationContext.getBean(PG_BEAN)
} else {
// register a bean under the name 'postGres' and store a reference to it in postgres
// https://stackoverflow.com/a/20634968/2648
}
checkPostgres(postgres)
}
private checkPostres(postgresBean) {
// check that the database is available, throw an exception if it's not, return
// postgresBean if it is
}
}