加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-16 19:09:13 所属栏目:安全 来源:网络整理
导读:我最近从Slick-2切换到Slick-3.一切都与slick-3工作非常好.但是,谈到交易时我遇到了一些问题. 我看到不同的问题和示例代码,其中事务和withPinnedSession用于处理事务.但我的情况略有不同.可以在查询中应用转义和与PinnedSession两者.但是我想做的是将相同的
我最近从Slick-2切换到Slick-3.一切都与slick-3工作非常好.但是,谈到交易时我遇到了一些问题.
我看到不同的问题和示例代码,其中事务和withPinnedSession用于处理事务.但我的情况略有不同.可以在查询中应用转义和与PinnedSession两者.但是我想做的是将相同的会话传递给另一种方法,该方法将执行一些操作,并希望将多个方法包装在相同的事务中.

我有以下的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()方法.
如果我们需要做一些事务,可以通过在db.withTransaction块中使用insertWithTransaction()来实现.

例如:

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

但是使用slick-3,事务只能在查询上应用.
这意味着,无论我们需要在插入之后集中做一些逻辑,这是可能的.每个开发人员需要手动处理这些方案,如果他们正在使用事务.我相信这可能会导致错误.我试图在插入操作中抽象整个逻辑,以便实现者只需要担心事务成功/失败

有什么其他的方式,在slick-3中,我可以将相同的会话传递给多个方法,以便可以在单个数据库会话中完成所有操作.

解决方法

你缺少一些东西:.transactionnaly不适用于查询,而是适用于DBIOAction.
然后,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

操作由select查询和与第一个查询返回的行一样多的删除查询组成.所有这些都创建在事务中执行的DBIOAction.

然后,为了对数据库运行操作,你必须调用db.run,所以,像这样:

val f: Future[Unit] = db.run(action)

现在回到你的例子,假设你想在插入后应用更新查询,你可以这样创建一个动作

val action = (for {
  entity <- (query returning query.map(obj => obj) += row)
  _ <- query.map(_.foo).update(newFoo)
} yield entity).transactionnaly

希望它有帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读