加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 如何使用事务构建数据库访问层

发布时间:2020-12-16 18:47:19 所属栏目:安全 来源:网络整理
导读:我尝试将应用程序迁移到Slick 3.0.我想为Slick 3.0做一笔交易.我知道该怎么做,但我想问一下课程结构. 请查看示例存储库: Slick 2.1的一些存储库(或DAO): class UserRepository { def all()(implicit: Session): Seq[User] = users.run def insert(user: Us
我尝试将应用程序迁移到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
从一个事务中的用户和汽车存储库返回最后的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

解决方法

尽可能长时间地将插入保留为DBIOActions,根据需要进行组合,然后进行实际的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)

编辑:澄清的消息

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读