Slick 3 - multiple calls to db.run () in one transaction

I have a model repository class with byId and save metdhods

def byID(id:Long) = db.run{ query.filter(_.id === id).result }.map(_.headOption)
def save(model:User) = db.run{ query.filter(_.id===model.id).update(model) }

      

Now I want to use both of these methods, first load the user, then change anything and then save the user like this

userRepository.byID(5L).map{_.map{user =>
  val newuser = user.copy(name = "John")
  userRepository.save(newuser)            
}}

      

How can I do this in one transaction?

+3


source to share


1 answer


I think slick 3 does not support transaction that spans different futures, and when you call db.run

, you transmit DBIO[SomeType]

and receive Future

. The good news is that you can instead link your DBIOs by structuring your API in a slightly different way:

def byID(id:Long) = query.filter(_.id === id).result }.map(_.headOption)
def save(model:User) = query.filter(_.id===model.id).update(model)

      



And then:

db.run(userRepository.byID(5L).flatMap { users => 
  DBIO.sequence(users.map { user =>
    userRepository.save(user.copy(name = "John"))            
  })
}.transactionally)

      

+1


source







All Articles