【问题标题】:Do own stuff in Slick transaction在 Slick 交易中做自己的事情
【发布时间】:2016-09-02 18:17:51
【问题描述】:

我正在使用 Slick 3.1.1,我想在 Slick 事务上实现我自己的东西。

def findSomeProducts = table.getSomeProducts() //db operation
def productTableUpdate = doSomeStuff1() //db operation
def priceTableUpdate = doSomeStuff2() //db operation

def updateElasticCache = updateIndexOfProduct() //this is not a database operation

我有这些示例函数。首先,我从 db 获得了一些产品,并且在我更新了表格之后。最后我需要运行 updateElasticCache 方法。如果 updateElasticCache 方法失败,我想回滚整个数据库进程。

我无法使用 (for { ... } yield ()).transactionally 这个代码,因为它不适用于我的情况。这个“事务性”正在等待数据库操作。但我想添加另一个不是数据库进程的功能。

有可能吗?我怎样才能实现它?

【问题讨论】:

    标签: scala slick slick-3.0


    【解决方案1】:

    DBIO.from

    是的!可以使用 DBIO 操作组合和DBIO.from

    在 slick 中的 db 逻辑之间添加非 db 逻辑

    请注意,“你自己的东西”应该返回一个未来,未来可以转换为 DBIO 并且可以与通常的数据库操作一起组成。

    DBIO.from 可以帮助您。下面是它的工作原理。 DBIO.from 接受未来并将其转换为 DBIOAction。现在您可以将这些操作与通常的 db 操作组合在一起,以在事务中执行非 db 操作以及 db 操作。

    def updateElasticCache: Future[Unit] = Future(doSomething())
    

    现在假设我们有一些数据库操作

    def createUser(user: User): DBIO[Int] = ???
    

    如果更新缓存失败,我希望 createUser 回滚。所以我做了以下

    val action = createUser.flatMap { _ => DBIO.from(updateElasticCache()) }.transactionally
    db.run(action)
    

    现在如果updateElasticCache 失败整个tx 将失败并且一切都将回滚到正常状态。

    示例

    你可以使用 for comprehension 让它看起来不错

    def updateStats: DBIO[Int] = ???
    val rollbackActions =
      (for {
         cStatus <- createUser()
         uStatus <- updateStats()
         result <- DBIO.from(updateElasticCache())
       } yield result).transactionally
     db.run(rollbackActions)
    

    如果 updateElasticCache 未来失败,一切都会回滚

    【讨论】:

    • 感谢您的回答。我正在尝试重构我的功能。我的 db-operation 函数的返回类型与 DBIO 不同。它不返回 DBIO[T],而是返回 JdbcProfile.this.DriverAction[Int, NoStream, Write]。 ` def testUpdate(productId: Int, text: String): JdbcProfile.this.DriverAction[Int, NoStream, Write] = { val q = for { p
    • @sydboraa updateElasticCache() 应该返回 Future[_] 然后你可以将它包装在 DBIO.from(updateElasticCache()) 中。或def updateElasticCache: DBIO[_] = DBIO.from { doSomething() } doSomething 依次返回Future[_]
    • @sydboraa DBIODriverAction 的类型别名
    • .transactionally 方法需要什么样的导入?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    相关资源
    最近更新 更多