在Slick 3中共享多个方法之间的数据库会话

时间:2015-05-21 10:43:56

标签: scala transactions slick

我最近从Slick-2切换到Slick-3。一切都与光滑-3一起工作得非常好。但是,在交易方面我遇到了一些问题。 我看到了transactionallywithPinnedSession用于处理事务的不同问题和示例代码。但我的情况略有不同。 transcationally和withPinnedSession都可以应用于Query。但我想要做的是将同一个会话传递给另一个方法,该方法将执行一些操作并希望在同一事务中包装多个方法。

我有下面的slick-2代码,我不知道如何用Slick-3实现这个。

def insertWithTransaction(row: TTable#TableElementType)(implicit session: Session) = {
      val entity = (query returning query.map(obj => obj) += row).asInstanceOf[TEntity]
      // do some operations after insert
      //eg: invoke another method for sending the notification
      entity
}

override def insert(row: TTable#TableElementType) = {
    db.withSession {
      implicit session => {
        insertWithTransaction(row)
      }
    }
}

现在,如果某人对交易不感兴趣,他们只需调用insert()方法即可。 如果我们需要进行一些交易,可以使用insertWithTransaction()块中的db.withTransaction来完成。

例如:

db.withTransaction { implicit session =>
    insertWithTransaction(row1)
    insertWithTransaction(row2)
    //check some condition, invoke session.rollback if something goes wrong
}

但是使用slick-3,事务上只能应用于查询。 这意味着,无论我们需要在插入后集中执行某些逻辑,都有可能。如果他们使用事务,每个开发人员都需要显式地手动处理这些场景。我相信这可能会导致错误。我试图在插入操作中抽象整个逻辑,以便实现者只需要担心事务成功/失败

还有其他方法,在slick-3中,我可以将同一个会话传递给多个方法,以便一切都可以在单个数据库会话中完成。

1 个答案:

答案 0 :(得分:1)

您遗失了一些内容:O(N)并不适用于.transactionally,而是适用于Query。 然后,DBIOAction可以通过使用monadic组合由多个查询组成。

以下是来自文档的例子:

DBIOAction

val action = (for { ns <- coffees.filter(_.name.startsWith("ESPRESSO")).map(_.name).result _ <- DBIO.seq(ns.map(n => coffees.filter(_.name === n).delete): _*) } yield ()).transactionally action查询和与第一个查询返回的行一样多select个查询组成。所有创建在事务中执行的delete

然后,要对数据库运行操作,您必须调用DBIOAction,所以,像这样:

db.run

现在,回到你的例子,让我们说你想在插入后应用val f: Future[Unit] = db.run(action) 查询,你可以用这种方式创建一个动作

update

希望它有所帮助。