我正在使用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
我有这些示例函数。首先,从数据库中获取一些产品,然后更新表。最后,我需要运行updateElasticCache方法。如果updateElasticCache方法失败,我想回滚整个数据库过程。
我不能用
(for { ... } yield ()).transactionally
此代码,因为它不适用于我的情况。这个“交易地”正在等待数据库操作。但是我想添加另一个功能,它不是数据库进程。可能吗?我该如何实现?
最佳答案
DBIO.from
是的 !!!可以使用DBIO操作组合和DBIO.from
在非光滑的db逻辑之间添加非db逻辑
请注意,“您自己的东西”应该返回一个future,future可以转换为DBIO,并且可以与通常的db操作一起组成。DBIO.from
可以帮助您。下面是它的工作原理。 DBIO.from
继承了 future ,并将其转换为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
将会失败,一切都会回滚到正常状态。示例
您可以使用它来使它看起来不错
def updateStats: DBIO[Int] = ???
val rollbackActions =
(for {
cStatus <- createUser()
uStatus <- updateStats()
result <- DBIO.from(updateElasticCache())
} yield result).transactionally
db.run(rollbackActions)
如果
updateElasticCache
future失败,一切都会回滚关于scala - 在Slick交易中拥有自己的东西,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39298581/