光滑 3 笔交易

Slick 3 Transactions

我对 slick 3 文档描述交易的方式感到困惑。我有看起来像这样的光滑 2 代码:

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

我如何在 slick 3 中跨越事务?

请查看此处的文档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)

这样 Slick 仍然以被动方式处理所有操作,但它在一个事务中按顺序运行它们。

因此您的示例将如下所示:

def doSomething(???) = (for {
  _ <- userDao.doSomething(???)
  _ <- addressDao.doSomething(???)
  _ <- contactDao.doSomething(???)
} yield()).transactionally
val dbAction = (
  for {
    user <- userTable.doSomething
    address <- addressTable.doSomething
    contact <- contactTable.doSomething
  } yield()
).transactionally

val resultFuture = db run dbAction

您只需要将您的操作包装到 'transactionally' 中。 Slick 会将 运行 所有包装的数据库操作作为事务处理。

除了具有更多reactive/functional/async 方式 编写代码的标准优势外,它还允许一些性能改进 .就像它可以在运行时确定多个操作是否可以使用同一个会话一样。在 Slick 2.0 中,无论何时您使用 'withTransaction' 或 'withSession' 都会打开一个新的 jdbc 会话,而在这里它有可能重用相同的会话。