Slick 3 Transactions

孤街醉人 提交于 2019-12-03 09:50:15

问题


I'm confused by the way the slick 3 documentation describes transactions. I have slick 2 code that looks like this:

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

How can i span a transaction in slick 3?


回答1:


Please have a look at the documentation here http://slick.typesafe.com/doc/3.0.0/dbio.html#transactions-and-pinned-sessions

The idea is that you wrap a sequence of IO operations into a transactionally like shown in this example:

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)

This way Slick still process all the operations reactively, but it runs them all in one transaction sequentially.

So your example would look like this:

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



回答2:


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

val resultFuture = db run dbAction

You just need to wrap your action into 'transactionally'. Slick would take care of running all wrapped DB actions as a transaction.

Apart from the standard advantages of having a more reactive/functional/async way of writing code, it allows couple of performance improvements. Like it can determine at runtime if multiple actions can use the same session or not. In Slick 2.0, whenever you use 'withTransaction' or 'withSession' that opens a new jdbc session while here it has potential to reuse the same.



来源:https://stackoverflow.com/questions/30327617/slick-3-transactions

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!