Reputation: 266988
I have my DAO code that looks like:
UserDao.scala:
def save(user: User)(implicit session: Session) ... {
....
}
Then UserService:
def save(user: User) .. {
db.withSession { implicit session =>
userDao.save(user)
}
}
I have other ABCService classes that have the exact same pattern for my other models.
Now my question is, now I want to create a transaction around multiple calls, is this possible?
OtherService:
userService.save(user)
accountService.save(account)
Now if either of those calls fail, I want it to rollback. The problem is the sessions are handled indepentaley currently in each Service class, so if the userService.save(user) passes but accountService.save fails, I have data that is in a bad state.
How can I solve this problem?
Upvotes: 1
Views: 1260
Reputation: 47061
Maybe you could give a look at https://github.com/tim-group/scalaquery_nested
Their implementation looks very concise: https://github.com/tim-group/scalaquery_nested/blob/master/src/main/scala/com/timgroup/scalaquery_nested/NestedScalaQuerySessionsAndTransactions.scala
But they use exception to detect wrapped session, not sure whether it has performance issue for complicated session/transaction nesting..
Upvotes: 0
Reputation: 55569
Slick has withTransaction
that will work exactly the same as withSession
, except that everything is executed within a transaction.
Require the signatures of your service functions to have an implicit: Session
parameter (if they're to be used within a transaction), and remove the provisioned Session
from within them:
def save(user: User)(implicit: Session) {
userDao.save(user)
}
Then provide that Session
via withTransaction
:
db.withTransaction{ implicit session =>
userService.save(user)
accountService.save(account)
}
Upvotes: 7