作成した DAO レイヤーに行き詰まりました。単一のケースでは問題なく動作しますが、トランザクション ブロックで複数の Bean インスタンスを永続化する必要がある場合、自分自身をコーナーにコーディングしていることに気付きます。なんで?以下の DAO create メソッドを確認してください。
def create(e: Entity): Option[Int] =
db.handle withSession { implicit ss: Session=>
catching( mapper.insert(e) ) option match {
case Some(success) => Some(Query(sequenceID))
case None => None
}
}
セッション ブロック内で発生するクエリは自動コミットに設定されているため、複数の永続化操作をトランザクション ブロックにラップすることはできません。たとえば、これは、新しいメンバーのサブスクリプションを処理する理解のために簡略化されたものです。
val result = for{
u <- user.dao.create(ubean)
m <- member.dao.create(mbean)
o <- order.dao.create(obean)
} yield (u,m,o)
result match {
case Some((a,b,c)) => // all good
case _ => // failed, need to rollback here
}
手動でクエリを実行することもできますが、それは醜い速さになります
db.handle withSession { implicit ss: Session=>
ss.withTransaction {
val result = for{
u <- safe( UserMapper.insert(ubean) )
...
}
def safe(q: Query[_]) =
catching( q ) option match {
case Some(success) => Some(Query(sequenceID))
case None => None
}
}
}
DAOレイヤーにカプセル化するのではなく、アプリケーション全体でデータベース、セッションなどを提供する必要があるため、エラー処理を複製することになります
この問題を回避する方法について、ここで賢明なアドバイスを持っている人はいますか? 私は理解のための簡潔さが本当に好きです、Scalaは岩です;-)、アイデアは大歓迎です!