我目前有一个问题需要处理。 我试图异步管理一个slick2.0事务。原因是与我合作的未来。
我编写了自己的方法来与光滑异步处理会话:
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
}
}
我像这样使用它(注入了dataSource):
withAsyncTransaction { implicit session =>
... CRUD
}
stacktrace:
The datasource has been shutdown.
java.lang.IllegalStateException: The datasource has been shutdown.
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:62)
偶尔会发生错误,并且它不依赖于连接池。与boneCP相同的问题。有人有想法吗?
将非常感谢帮助。 OliverKK
答案 0 :(得分:2)
我不确定究竟是什么导致了您所看到的错误,但我刚从经验中了解到,将期货,光滑和交易结合起来是令人头疼的问题。您编写的代码似乎应该可以正常工作,除了有部分浮油假设自动提交设置没有在其背后进行更改。
请参阅withTransaction
的实施:https://github.com/slick/slick/blob/06ee4edade81633db10724a858f427deb563edfc/src/main/scala/scala/slick/jdbc/JdbcBackend.scala#L476
它假定其私有var inTransaction
是最新的,并且如果它不认为它已经在事务中,则会在操作结束时将autocommit设置为true。这意味着您使用已创建的调用withTransaction
的会话编写的任何代码都将提交事务并将自动提交重置为true。现在,只要你没有调用withTransaction
,这似乎很好,但是当你可能没想到它时,有一些灵活的操作在内部调用它。例如,如果您使用++=
执行批量插入,它将调用withTransaction
并最终提交您已创建的事务,并且之后执行的每个语句都将自动提交。