【问题标题】:How to structure database access layer with transactions如何使用事务构建数据库访问层
【发布时间】:2015-07-09 16:33:04
【问题描述】:

我尝试将应用程序迁移到 Slick 3.0。我想为 Slick 3.0 进行交易。我知道该怎么做,但我想询问类结构。 请查看示例存储库:

Slick 2.1 的一些存储库(或 DAO):

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)
  ...
}

为了在 Slick 2.1 中进行交易,我可以创建一个可以进行交易的服务:

db.withTransaction{ implicit session =>
     userRepository.insert(user)
     carRepository.insert(car)
}

所以目前我有用于数据库访问的存储库(或 DAO)和用于更通用逻辑的服务。

Slick 3.0 的一些存储库(或 DAO):

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)
  ...
}

在 Slick 3.0 中,我们可以在 DBIOActions 上执行事务,但是当我们具有如上所示的结构时,这是不可能的 因为期货。我可以创建一些 UserCarRepository 类来进行交易,但我认为这不是最好的。 为了克服这种情况,我在存储库(或 DAO)中公开 DBIOActions,然后在其他层混合 DBIOActions 在一个事务中从 User 和 Car 存储库中返回 Future (下一层可能是对 future 进行操作的服务)。 当我们有更多用于事务的存储库时,它可能会有点混乱。

如何为 Slick 3.0 构建它?如何在不同存储库上为事务获得更松散的耦合?

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

【问题讨论】:

    标签: scala playframework slick


    【解决方案1】:

    尽可能长时间地将插入保持为 DBIOAction,根据需要组合它们,然后执行实际的 DB 查询。草图:

    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)
    

    编辑:澄清消息

    【讨论】:

    • 可能没问题,但是当我们混合对不同表的访问时,它会破坏单一职责。你想如何组织这个?我想您的解决方案将访问权限保持在一个类中。
    • 我的意思可能有点不清楚。我已经编辑了答案并添加了一些上下文。如果您愿意,您可以将执行实际数据库查询的代码放在一个类中,或者您可以将它们混合到其余代码中,并在进行数据库查询时牢记在心,这取决于您对什么感到满意。
    猜你喜欢
    • 2019-07-31
    • 2010-09-13
    • 1970-01-01
    • 2010-09-12
    • 2012-08-30
    • 2013-12-05
    • 2011-04-18
    • 2011-02-15
    • 2014-09-15
    相关资源
    最近更新 更多