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

sbb*_*sbb 7 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
Run Code Online (Sandbox Code Playgroud)

我有这些示例函数.首先,我正在从db中获取一些产品,并在我更新表之后.最后我需要运行updateElasticCache方法.如果updateElasticCache方法失败,我想回滚整个db procceses.

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

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

pam*_*amu 6

来自DBIO

是的!可以使用DBIO操作组合在非光滑的db逻辑之间添加非db逻辑DBIO.from

请注意,“您自己的东西”应该返回一个future,future可以转换为DBIO并可以与通常的db操作一起组成。

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

def updateElasticCache: Future[Unit] = Future(doSomething())
Run Code Online (Sandbox Code Playgroud)

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

def createUser(user: User): DBIO[Int] = ???
Run Code Online (Sandbox Code Playgroud)

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

val action = createUser.flatMap { _ => DBIO.from(updateElasticCache()) }.transactionally
db.run(action)
Run Code Online (Sandbox Code Playgroud)

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

您可以使用它来使它看起来不错

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

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