我正在使用Play Framework实现一个使用多个数据库的Web服务。通过指定db.database1 ...,db.database2 ...属性,在conf / application.conf中配置所有数据库。
启动时,play将尝试建立与数据库中配置的所有数据库的连接,如果一个连接失败,则服务将无法启动。
就我而言,并非所有数据库都是启动Web服务所必需的,但如果某些数据库不可用,则Web服务仍然可以使用有限的功能运行。由于并非所有数据库都在我的控制之下,因此我的Web服务处理连接错误至关重要。
因此我的问题是:
有没有办法
我更喜欢解决方案2.
我正在使用scala版本2.11.7的Play版本2.4.2。
由于整个例外填充多个页面,我只在这里插入第一行:
CreationException: Unable to create injector, see the following errors:
1) Error in custom provider, Configuration error: Configuration error[Cannot connect to database [foo]]
while locating play.api.db.DBApiProvider
while locating play.api.db.DBApi
for field at play.api.db.NamedDatabaseProvider.dbApi(DBModule.scala:80)
while locating play.api.db.NamedDatabaseProvider
at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149)
at play.api.db.DBModule$$anonfun$namedDatabaseBindings$1.apply(DBModule.scala:34):
Binding(interface play.api.db.Database qualified with QualifierInstance(@play.db.NamedDatabase(value=appstate)) to ProviderTarget(play.api.db.NamedDatabaseProvider@1a7884c6)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
Caused by: Configuration error: Configuration error[Cannot connect to database [foo]]
at play.api.Configuration$.configError(Configuration.scala:178)
at play.api.Configuration.reportError(Configuration.scala:829)
at play.api.db.DefaultDBApi$$anonfun$connect$1.apply(DefaultDBApi.scala:48)
at play.api.db.DefaultDBApi$$anonfun$connect$1.apply(DefaultDBApi.scala:42)
at scala.collection.immutable.List.foreach(List.scala:381)
at play.api.db.DefaultDBApi.connect(DefaultDBApi.scala:42)
at play.api.db.DBApiProvider.get$lzycompute(DBModule.scala:72)
答案 0 :(得分:0)
我记得存在一个全局设置配置文件,用于在应用程序启动时捕获错误。
看看这里:https://www.playframework.com/documentation/2.0/ScalaGlobal我知道你正在使用更新的游戏版本,但你会更全面地了解它是如何工作的。
在Play 2.4.x中,此文件已被删除并立即使用DI(https://www.playframework.com/documentation/2.4.x/GlobalSettings)。
答案 1 :(得分:0)
为了解决我的问题,我最终为BoneCP编写了自己的包装器。这样,ConnectionPools的初始化就在我手中,我可以处理连接错误。
我在新的配置文件db
中使用前缀database
(以便Play不会自动解析其内容),而不是使用database.conf
前缀。
object ConnectionPool {
private var connectionPools = Map.empty[String, BoneCP]
val config = ConfigFactory.parseFile(new File("conf/database.conf"))
private def dbConfig(dbId: String): ConfigObject = {
config.getObject("database." + dbId).asInstanceOf[ConfigObject]
}
def createConnectionPool(dbId: String): BoneCP = {
val dbConf = dbConfig(dbId)
val cpConfig: BoneCPConfig = new BoneCPConfig()
cpConfig.setJdbcUrl(dbConf.get("url").unwrapped().toString)
cpConfig.setUsername(dbConf.get("user").unwrapped().toString)
cpConfig.setPassword(dbConf.get("password").unwrapped().toString)
new BoneCP(cpConfig)
}
def getConnectionPool(dbId: String): BoneCP = {
if(!connectionPools.contains(dbId)) {
val cp = createConnectionPool(dbId)
connectionPools = (connectionPools + (dbId -> cp))
}
connectionPools(dbId)
}
def getConnection(dbId: String): Connection = {
getConnectionPool(dbId).getConnection()
}
def withConnection[T](dbId: String)(fun: Connection => T): T = {
val conn = getConnection(dbId)
val t = fun(conn)
conn.close()
t
}
}