Слайк 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, в то время как здесь он может повторно использовать одно и то же.