未来 sql 数据库连接不稳定时的执行行为
Future sql execution behavior while database connection is unstable
我在期货执行 SQL 查询时遇到问题。
虽然数据库连接是很好的未来,但在连接池的会话中异步执行 sql 查询。 TypeSafe Slick 帮助我从池中获取会话。
当数据库连接中断时,新的期货无法执行查询并等待。我没有看到任何 onComplete 回调。
当数据库连接再次良好时,所有以前的期货仍在等待。只有重新连接后出现的新期货才能执行它们的工作。
请告知如何告诉已经调用的等待期货关于数据库重新连接并继续他们的工作,或者在完成失败时进行回调。
我对 c3p0 ComboPooledDataSource 的配置:
val ds = new ComboPooledDataSource
ds.setDriverClass("oracle.jdbc.OracleDriver")
ds.setJdbcUrl(jdbcUrl)
ds.setInitialPoolSize(20)
ds.setMinPoolSize(1)
ds.setMaxPoolSize(40)
ds.setAcquireIncrement(5)
ds.setMaxIdleTime(3600)
//Connection testing
ds.setTestConnectionOnCheckout(false)
ds.setTestConnectionOnCheckin(false)
ds.setIdleConnectionTestPeriod(10)
//Connection recovery
ds.setBreakAfterAcquireFailure(false)
ds.setAcquireRetryAttempts(30)
ds.setAcquireRetryDelay(10000)
val databasePool = Database.forDataSource(ds)
// Typesafe Slick session handling
def withClient[T](body: Session => T) = {
databasePool.withSession(body)
}
期货在这里创建:
class RewardActivatorHelper {
private implicit val ec = new ExecutionContext {
val threadPool = Executors.newFixedThreadPool(1000)
def execute(runnable: Runnable) {threadPool.submit(runnable)}
def reportFailure(t: Throwable) {throw t}
}
case class FutureResult(spStart:Long, spFinish:Long)
def activateReward(msg:Msg, time:Long):Unit = {
msg.users.foreach {
user =>
val future:Future[FutureResult] = Future {
val (spStart, spFinish) = OracleClient.rewardActivate(user)
FutureResult(spStart, spFinish)
}
future.onComplete {
case Success(futureResult:FutureResult) =>
//do something
case Failure(e:Throwable) => log.error(e.getMessage())
}
}
}
问题由 setTestConnectionOnCheckout(true)
解决
我在期货执行 SQL 查询时遇到问题。
虽然数据库连接是很好的未来,但在连接池的会话中异步执行 sql 查询。 TypeSafe Slick 帮助我从池中获取会话。
当数据库连接中断时,新的期货无法执行查询并等待。我没有看到任何 onComplete 回调。
当数据库连接再次良好时,所有以前的期货仍在等待。只有重新连接后出现的新期货才能执行它们的工作。
请告知如何告诉已经调用的等待期货关于数据库重新连接并继续他们的工作,或者在完成失败时进行回调。
我对 c3p0 ComboPooledDataSource 的配置:
val ds = new ComboPooledDataSource
ds.setDriverClass("oracle.jdbc.OracleDriver")
ds.setJdbcUrl(jdbcUrl)
ds.setInitialPoolSize(20)
ds.setMinPoolSize(1)
ds.setMaxPoolSize(40)
ds.setAcquireIncrement(5)
ds.setMaxIdleTime(3600)
//Connection testing
ds.setTestConnectionOnCheckout(false)
ds.setTestConnectionOnCheckin(false)
ds.setIdleConnectionTestPeriod(10)
//Connection recovery
ds.setBreakAfterAcquireFailure(false)
ds.setAcquireRetryAttempts(30)
ds.setAcquireRetryDelay(10000)
val databasePool = Database.forDataSource(ds)
// Typesafe Slick session handling
def withClient[T](body: Session => T) = {
databasePool.withSession(body)
}
期货在这里创建:
class RewardActivatorHelper {
private implicit val ec = new ExecutionContext {
val threadPool = Executors.newFixedThreadPool(1000)
def execute(runnable: Runnable) {threadPool.submit(runnable)}
def reportFailure(t: Throwable) {throw t}
}
case class FutureResult(spStart:Long, spFinish:Long)
def activateReward(msg:Msg, time:Long):Unit = {
msg.users.foreach {
user =>
val future:Future[FutureResult] = Future {
val (spStart, spFinish) = OracleClient.rewardActivate(user)
FutureResult(spStart, spFinish)
}
future.onComplete {
case Success(futureResult:FutureResult) =>
//do something
case Failure(e:Throwable) => log.error(e.getMessage())
}
}
}
问题由 setTestConnectionOnCheckout(true)
解决