I'm using Slick 3.1.1 and i would like to implement my own stuff on Slick transaction.
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
I have these sample functions. Firstly, I'm getting some products from db and after i'm updating the tables. At the end I need to run updateElasticCache method. If updateElasticCache method fails, I would like to rollback whole db procceses.
I can't use
(for { ... } yield ()).transactionally this code because it's not applicable for my cases. This 'transactionally' is waiting a db action. But I want to add another functionality which is not a db-process.
Is it possible? How can I achieve it?
DBIO.from
Yes !!! its possible to add non db logic in between db logic in slick using DBIO actions composition and
DBIO.from
Note that "your own stuff" should return a future, future can be converted to DBIO and can be composed along with usual db actions.
DBIO.from can help you with this. Here is how it works.
DBIO.from takes a future and converts it into a DBIOAction. now you can compose these actions with usual db actions to do non-db operations along with db operations in a transaction.
def updateElasticCache: Future[Unit] = Future(doSomething())
now lets say we have some db actions
def createUser(user: User): DBIO[Int] = ???
I want createUser to rollback if updating cache fails. so i do the following
val action = createUser.flatMap { _ => DBIO.from(updateElasticCache()) }.transactionally db.run(action)
now if
updateElasticCache fails whole
tx will fail and everything will rollback to normal state.
Example
You can use for comprehension to make it look good
def updateStats: DBIO[Int] = ??? val rollbackActions = (for { cStatus <- createUser() uStatus <- updateStats() result <- DBIO.from(updateElasticCache()) } yield result).transactionally db.run(rollbackActions)
everything roll backs if
updateElasticCache future fails