2015-05-19 86 views
14

我很困惑slick 3文檔描述交易的方式。我有看起來像這樣的華而不實2代碼:Slick 3交易

def doSomething(???) = DB.withTransaction { implicit session => 
    userDao.doSomething(???) 
    addressDao.doSomething(???) 
    contactDao.doSomething(???) 
} 

我怎樣才能在一個光滑的3交易?

回答

16

請看看這裏的文檔http://slick.typesafe.com/doc/3.0.0/dbio.html#transactions-and-pinned-sessions

的想法是,你包的IO操作的順序爲transactionally像這個例子所示:

val a = (for { 
    ns <- coffees.filter(_.name.startsWith("ESPRESSO")).map(_.name).result 
    _ <- DBIO.seq(ns.map(n => coffees.filter(_.name === n).delete): _*) 
} yield()).transactionally 

val f: Future[Unit] = db.run(a) 

這樣油滑仍然處理所有這些操作是被動的,但是它依次在一個事務中運行它們。

所以,你的例子是這樣的:

def doSomething(???) = (for { 
    _ <- userDao.doSomething(???) 
    _ <- addressDao.doSomething(???) 
    _ <- contactDao.doSomething(???) 
} yield()).transactionally 
+5

傷心的是,我必須處理該抽象層次上的動作連接。 – Bomgar

+2

另外,我必須在那個抽象層上「運行」它令人討厭 – Bomgar

+0

嗯,它不是一個真正的抽象層次,它只是期貨的鏈接。請注意'for'中的3行不會在同一個線程中執行。我認爲這是支付被動數據庫訪問的代價。如果你想擁有異步非阻塞功能,那麼與期貨和合作夥伴一起工作。是做到這一點的自然方式。 –

13
val dbAction = (
    for { 
    user <- userTable.doSomething 
    address <- addressTable.doSomething 
    contact <- contactTable.doSomething 
    } yield() 
).transactionally 

val resultFuture = db run dbAction 

你只需要來包裝你行動統一到「事務」。 Slick會負責將所有包裝的數據庫操作作爲事務運行。

除了具有編寫代碼的更反應性/功能/異步方式的標準的優點,它允許幾個性能改進。就像它可以在運行時確定多個操作是否可以使用同一會話一樣。在Slick 2.0中,無論何時使用'withTransaction'或'withSession'打開一個新的jdbc會話,在這裏它都有可能重複使用。