2014-03-04 65 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並最終提交您創建的事務,並且在執行之後執行的每個語句都將自動提交。

相關問題