2015-06-22 14 views
8

Attualmente ho un set di oggetti di accesso ai dati denominato con la convenzione *SlickRepo. Così, per esempio, UserSlickRepo, DistributionSlickRepo, ContentSlickRepo, ecc ...Metodi Slick Repo che partecipano tutti alla Transazione di un servizio

Ciascuno di questi metodi Repos hanno su di loro che, in fondo seguono questa convenzione:

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

momento fino ad un livello di servizio, abbiamo cuocere in questo classe di pronti contro termine e noi abbiamo i metodi che assomigliano a questo:

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

    } 
} 

ora il desiderio di avere createSomethingGood effettivamente eseguito i due metodi di pronti contro termine all'interno di una transazione. Dal momento che tutta la roba di Slick è bloccata nei metodi di replica specifici di Slick, qual è il modo migliore per farlo? Non sono contrario ad avere il codice specifico di Slick nelle mie classi *ServiceImpl (voglio dire strano, ma ok), tuttavia ciò significa che devo cambiare le mie classi Repo per rimuovere il codice di tipo getDatabase withDynSession tutti insieme e invece passare una sessione da il livello di servizio? Per me, questo sembra ... sbagliato.

+0

È possibile avere un servizio transazionale con sessione implicita come [suggerito qui] (http://stackoverflow.com/questions/28398482/how-we-use-slick-transaction-on-service-layer-for-making- sistema a-transazione). Nota a margine: sei sicuro che i Repos siano in realtà Repository, non oggetti DAO? – MirMasej

risposta

0

Forse c'è un altro modo. Non l'ho provato da solo, ma l'idea è che si possa avere un wrapper Session che viene effettivamente passato al Repo.

Questo involucro dovrebbe essere creato al livello di servizio, ma si può astrarre l'implementazione specifica su un oggetto associato in modo che il livello di servizio in realtà non trattare con Slick, ma piuttosto qualcosa di simile

SessionWrapper.transactional: Session 

Spero che questo aiuti, aggiungerò di più alla risposta se avrò la possibilità di provare da solo.

4

Dal mio punto di vista il giusto approccio è quello di aggiungere createSomething e createSomethingElse ad uno *Repo (SomethingRepo o SomethingElseRepo) il metodo transazionale (withTransaction {...}). Non è una soluzione bellissima ma il più semplice possibile per me e perché queste entità sono collegate logicamente (che possiamo vedere da questo codice (dep.somethingRepo.createSomething, dep.somethingElseRepo.createSomethingElse)) Penso che non sia una grande violazione combinare operazione su 2 entità in una classe DAO. Per favore, aggiustami, se sbaglio.

+0

Non sono sicuro che la creazione di una classe * Repo personalizzata ogni volta che un metodo di servizio debba chiamare due chiamate repo all'interno di una transazione è fattibile nel mio caso. – ThaDon

+0

@ThaDon, non creare personalizzato ma riutilizzarne uno già esistente. Nel tuo esempio sono 'SomethingRepo' o' SomethingElseRepo' – ka4eli