2015-05-19 14 views
14

Sono confuso dal modo in cui la documentazione 3 chiari descrive le transazioni. Ho codice chiazza di petrolio 2 che assomiglia a questo:Slick 3 Transazioni

def doSomething(???) = DB.withTransaction { implicit session => 
    userDao.doSomething(???) 
    addressDao.doSomething(???) 
    contactDao.doSomething(???) 
} 

come posso abbracciare una transazione in chiazza di petrolio 3?

risposta

16

prega di dare un'occhiata alla documentazione qui http://slick.typesafe.com/doc/3.0.0/dbio.html#transactions-and-pinned-sessions

L'idea è che si avvolge una sequenza di operazioni IO in un transactionally come illustrato in questo esempio:

val a = (for { 
    ns <- coffees.filter(_.name.startsWith("ESPRESSO")).map(_.name).result 
    _ <- DBIO.seq(ns.map(n => coffees.filter(_.name === n).delete): _*) 
} yield()).transactionally 

val f: Future[Unit] = db.run(a) 

questo modo Slick ancora elaborare tutti le operazioni in modo reattivo, ma le esegue tutte in un'unica transazione in sequenza.

Così il vostro esempio sarà simile a questa:

def doSomething(???) = (for { 
    _ <- userDao.doSomething(???) 
    _ <- addressDao.doSomething(???) 
    _ <- contactDao.doSomething(???) 
} yield()).transactionally 
+5

triste che ho a che fare con concatenazione di azioni su quel livello di astrazione. – Bomgar

+2

anche che devo "eseguirlo" su quel livello di astrazione è fastidioso – Bomgar

+0

Beh, non è davvero un livello di astrazione, è solo incatenamento del futuro. Nota che le 3 righe in 'for' non sono eseguite nello stesso thread. Penso che questo sia il prezzo da pagare per l'accesso DB reattivo. Se vuoi avere una funzionalità asincrona non bloccante, allora lavora con futures e co. è il modo naturale per farlo. –

13
val dbAction = (
    for { 
    user <- userTable.doSomething 
    address <- addressTable.doSomething 
    contact <- contactTable.doSomething 
    } yield() 
).transactionally 

val resultFuture = db run dbAction 

Hai solo bisogno di avvolgere la vostra azione in 'transazionale'. Slick si occuperà di eseguire tutte le azioni DB avvolte come una transazione.

Oltre ai vantaggi standard di avere un più reattivo/funzionale/asincrona modo di scrivere codice, permette paio di miglioramenti delle prestazioni. Come può determinare a runtime se più azioni possono utilizzare la stessa sessione o meno. In Slick 2.0, ogni volta che usi 'withTransaction' o 'withSession' che apre una nuova sessione jdbc mentre qui ha il potenziale per riutilizzare lo stesso.