2014-03-04 60 views
2

有一个问题,我目前不得不处理。 Iam试图异步管理slick2.0事务。原因是我工作的期货。异步事务导致IllegalStateException

我写我自己的方法,用油滑异步处理会话:

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同样的问题。有人有想法吗?

帮助将不胜感激。 OliverKK

+0

这很奇怪。我对Slick并不熟悉,但似乎偶尔会在DataSource上调用close()而不是连接,这是可能的吗? – brettw

+0

在Slick上阅读后,它显示使用期货与会议是危险的,所以我不知道你想要做什么是可能的。请参阅文档[此处](http://slick.typesafe.com/doc/2.0.1-RC1/connection.html),搜索警告“escapes”一词。我会建议在Slick论坛上提问。 – brettw

回答

2

我不确定究竟是什么导致了您所看到的错误,但我从经验中得知,合并期货,浮油和交易是一个令人头痛的处方。你写的代码看起来应该可以工作,除非有些浮油部分假设自动提交设置没有被改变。

withTransaction实现:https://github.com/slick/slick/blob/06ee4edade81633db10724a858f427deb563edfc/src/main/scala/scala/slick/jdbc/JdbcBackend.scala#L476

假设它的私人VAR inTransaction是最新的,并且会自动提交设置为true,在操作结束时,如果它不认为这是已经在交易。这意味着使用您创建的会话编写的任何代码将调用withTransaction将提交事务并将自动提交重置为true。现在,只要你不打电话withTransaction,这似乎很好,但当你可能没有想到它时,会有内部调用它的光滑操作。例如,如果使用++=执行批量插入,它将调用withTransaction并最终提交您创建的事务,并且在执行之后执行的每个语句都将自动提交。

相关问题