在Slick交易中拥有自己的东西

时间:2016-09-02 18:17:52

标签: scala slick slick-3.0

我使用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方法失败,我想回滚整个db procceses。

我无法使用 (for { ... } yield ()).transactionally此代码,因为它不适用于我的案例。这是“交易”'正在等待数据库操作。但我想添加另一个不是db-process的功能。

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

1 个答案:

答案 0 :(得分:4)

<强> DBIO.from

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

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

注意&#34;你自己的东西&#34;应该返回未来,将来可以转换为DBIO,并且可以与通常的数据库操作一起编写。

DBIO.from可以帮助您解决此问题。下面是它的工作原理。 DBIO.from占用未来并将其转换为DBIOAction。现在,您可以使用常规数据库操作组合这些操作,以便在事务中执行非数据操作以及数据库操作。

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将失败,一切都将回滚到正常状态。

示例

您可以使用理解来使其看起来不错

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

一切都会回滚