Слайк 3 Сделки

Меня смущает то, как документация slick 3 описывает транзакции. У меня есть пятно 2 кода, который выглядит так:

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

Как я могу заключить транзакцию в slick 3?

Ответы

Ответ 1

Пожалуйста, посмотрите здесь документацию http://slick.typesafe.com/doc/3.0.0/dbio.html#transactions-and-pinned-sessions

Идея состоит в том, что вы переносите последовательность операций ввода-вывода в 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

Ответ 2

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

val resultFuture = db run dbAction

Вам просто нужно перенести действие в транзакцию. Slick позаботится о том, чтобы выполнить все завершенные действия DB в качестве транзакции.

Помимо стандартных преимуществ наличия более реактивного/функционального/асинхронного способа написания кода, он позволяет несколько улучшений производительности . Как он может определить во время выполнения, если несколько действий могут использовать один и тот же сеанс или нет. В Slick 2.0 всякий раз, когда вы используете "withTransaction" или "withSession", который открывает новый сеанс jdbc, в то время как здесь он может повторно использовать одно и то же.