所有参与服务交易的Slick Repo方法

Tha*_*Don 8 scala slick-2.0

我目前有一组以约定命名的数据访问对象*SlickRepo.因此,例如,UserSlickRepo,DistributionSlickRepo,ContentSlickRepo,等...

这些Repos中的每一个都有基于此约定的方法:

trait SomethingRepoImpl extends SomethingRepo {
  val somethingRepo: SomethingRepo = new SomethingRepoImpl

  class SomethingRepoImpl extends SomethingRepo with MySlickDatastore {

    def getSomething(id: UUID): Either[SomethingNotFoundError, Something] = {
      getDatabase withDynSession {
        // Slick stuff
      }
    }
    def createSomething .....
  }
}
Run Code Online (Sandbox Code Playgroud)

现在在服务级别,我们在这个repo类中烘焙,我们的方法看起来像这样:

trait SomethingServiceImpl extends SomethingService {

  dep: SomethingRepo with SomethingElseRepo =>


  val somethingService = new SomethingServiceImpl

  class SomethingServiceImpl extends SomethingService {

    def createSomethingGood(): Either[SomeError, (Something, SomethingElse)] = {
      (dep.somethingRepo.createSomething, dep.somethingElseRepo.createSomethingElse)
    }

  }
}
Run Code Online (Sandbox Code Playgroud)

我们现在希望createSomethingGood在事务中实际运行两个repo方法.由于所有Slick内容都被锁定在Slick特定的Repo方法中,这样做的最佳方法是什么?我并不反对在我的*ServiceImpl类中使用特定于Slick的代码(我的意思很奇怪,但是确定),但这是否意味着我必须更改我的Repo类以一起删除getDatabase withDynSession类型代码,而是从服务传递会话层?对我而言,这似乎......错了.

Adr*_*pez 0

也许还有另一种方法。我自己还没有尝试过,但想法是您可以拥有一个实际传递到存储库的会话包装器。

该包装器必须在服务层创建,但您可以抽象伴随对象上的特定实现,这样服务层实际上并不处理 Slick,而是类似的东西

SessionWrapper.transactional: Session
Run Code Online (Sandbox Code Playgroud)

我希望这会有所帮助,如果我得到更改以亲自尝试一下,我会在响应中添加更多内容。