首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Slick 3中的多个方法之间共享数据库会话

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

Stack Overflow用户
提问于 2015-05-21 18:43:56
回答 1查看 1.2K关注 0票数 7

我最近从Slick-2切换到Slick-3。使用slick-3,一切都运行得很好。然而,当涉及到交易时,我遇到了一些问题。我见过使用transactionallywithPinnedSession处理事务的不同问题和示例代码。但我的情况略有不同。transcationally和withPinnedSession都可以在Query上应用。但我想要做的是将相同的会话传递给另一个方法,该方法将执行一些操作,并希望在同一事务中包装多个方法。

我有下面的slick-2代码,我不确定如何使用Slick-3实现这一点。

代码语言:javascript
复制
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()方法。如果我们需要做一些事务,可以通过在db.withTransaction块中使用insertWithTransaction()来完成。

例如:

代码语言:javascript
复制
db.withTransaction { implicit session =>
    insertWithTransaction(row1)
    insertWithTransaction(row2)
    //check some condition, invoke session.rollback if something goes wrong
}

但使用slick-3时,事务性只能应用于查询。这意味着,在我们需要在插入后集中做一些逻辑的地方,它都是可能的。如果使用事务,每个开发人员都需要手动显式地处理这些场景。我认为这可能会导致错误。我试图在insert操作中抽象出整个逻辑,这样实现者只需要关心事务的成功/失败

在slick-3中,有没有其他方法可以将相同的会话传递给多个方法,以便在单个db会话中完成所有操作。

EN

回答 1

Stack Overflow用户

发布于 2015-06-17 00:55:03

您遗漏了一些东西:.transactionally不适用于Query,而适用于DBIOAction。然后,可以使用一元组合将多个查询组合成一个DBIOAction

以下是文档中的一个示例:

代码语言:javascript
复制
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,因此,如下所示:

代码语言:javascript
复制
val f: Future[Unit] = db.run(action)

现在,回到您的示例,假设您想要在插入之后应用update查询,您可以这样创建一个操作

代码语言:javascript
复制
val action = (for {
  entity <- (query returning query.map(obj => obj) += row)
  _ <- query.map(_.foo).update(newFoo)
} yield entity).transactionally

希望能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30371450

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档