2

我目前必须处理一个问题。我正在尝试异步管理 slick2.0 事务。原因是我使用的期货。

我编写了自己的方法来使用 slick 异步处理会话:

def withAsyncTransaction[T](implicit block: Session => Future[T]): Future[T] = {
  val session = Database.forDataSource(dataSource).createSession()
  session.conn.setAutoCommit(false)
  block(session).recover {
    case e: Exception =>
      session.conn.rollback()
      session.conn.close()
      throw e
  }.map { v =>
    session.conn.commit()
    session.conn.close()
    v
  }
}

我像这样使用它(注入数据源):

withAsyncTransaction { implicit session =>
 ... CRUD
}

堆栈跟踪:

The datasource has been shutdown.
java.lang.IllegalStateException: The datasource has been shutdown.
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:62)

该错误是偶尔发生的,它不依赖于连接池。boneCP 也有同样的问题。有人有想法吗?

帮助将不胜感激。奥利弗KK

4

1 回答 1

2

我不确定究竟是什么导致了您所看到的错误,但我刚刚从经验中了解到,将期货、浮油和交易结合起来会让人头疼。您编写的代码似乎应该可以工作,除了 slick 的某些部分假定自动提交设置没有在其背后更改。

请参阅withTransactionhttps ://github.com/slick/slick/blob/06ee4edade81633db10724a858f427deb563edfc/src/main/scala/scala/slick/jdbc/JdbcBackend.scala#L476的实现

它假定它的私有 varinTransaction是最新的,如果它不认为它已经在事务中,它将在操作结束时将 autocommit 设置为 true。这意味着您使用已创建的调用会话编写的任何代码都withTransaction将提交事务并将自动提交重置为 true。现在,只要您不调用,这似乎很好withTransaction,但是当您可能不期望它时,有一些巧妙的操作会在内部调用它。例如,如果您用于++=执行批量插入,它将调用withTransaction并最终提交您创建的事务,并且您之后执行的每条语句都将自动提交。

于 2014-12-03T03:41:39.130 回答