web-dev-qa-db-ja.com

スリック3トランザクション

洗練された3のドキュメントがトランザクションを説明している方法に混乱しています。私は次のような滑らかな2つのコードを持っています:

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

Slick 3でトランザクションをスパンするにはどうすればよいですか?

15
Bomgar

こちらのドキュメントをご覧ください 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は引き続きすべての操作をリアクティブに処理しますが、すべてを1つのトランザクションで順番に実行します。

したがって、例は次のようになります。

def doSomething(???) = (for {
  _ <- userDao.doSomething(???)
  _ <- addressDao.doSomething(???)
  _ <- contactDao.doSomething(???)
} yield()).transactionally
17
Gregor Raýman
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セッションを開くと、ここで同じものを再利用できる可能性があります。

14
panther