scala - How to structure database access layer with transactions -


i try migrate application slick 3.0. make transaction slick 3.0. know how ask classes structure. please take on sample repositories:

some repositories (or dao) slick 2.1:

class userrepository {   def all()(implicit: session): seq[user] = users.run   def insert(user: user)(implicit: session): int = users.insert(user)   ... }  class carrepository {   def all()(implicit: session): seq[car] = cars.run   def insert(car: car)(implicit: session): int = cars.insert(car)   ... } 

in order transaction in slick 2.1 create service can transaction:

db.withtransaction{ implicit session =>      userrepository.insert(user)      carrepository.insert(car) } 

so have repositories (or daos) database access , services more general logic.

some repositories (or dao) slick 3.0:

class userrepository {   def all(): future[seq[user]] = db.run(users.result)   def insert(user: user): future[int] = db.run(users += user)    ... }  class carrepository {   def all(): future[seq[car]] = db.run(cars.result)   def insert(car: car): future[int] = db.run(cars += car)   ... } 

in slick 3.0 can transaction on dbioactions when have structure shown above not possible because of futures. create usercarrepository class transaction think not best one. in order overcome situation expose dbioactions in repositories (or daos) , in other layer mix dbioactions user , car repositories in 1 transaction return future @ end (next layer service operate on futures). when have more repositories transaction little bit messy.

how structure slick 3.0? how gain more loose coupling transaction on different repositories?

reading: https://github.com/playframework/play-slick/tree/master/samples https://github.com/slick/slick/issues/1084 https://groups.google.com/forum/#!topic/scalaquery/32co7lhbxos

keep inserts dbioactions long possible, compose them needed , actual db-query. sketch:

class userrepository {   def all() = users.result   def insert(user: user) = users += user    ... }  class carrepository {   def all() = cars.result   def insert(car: car) = cars += car   ... }  val composedinserts = (for {     _ <- new userrepository().insert(user)     _ <- new carrepository().insert(car) } yield ()).result  db.run(composedinserts.transactionally) 

edit: clarified message


Comments