2016-09-02 4 views
4

Я использую Slick 3.1.1, и я хотел бы реализовать свои собственные вещи на транзакции Slick.Собственный материал в транзакции Slick

def findSomeProducts = table.getSomeProducts() //db operation 
def productTableUpdate = doSomeStuff1() //db operation 
def priceTableUpdate = doSomeStuff2() //db operation 

def updateElasticCache = updateIndexOfProduct() //this is not a database operation 

У меня есть эти функции выборки. Во-первых, я получаю некоторые продукты из db и после обновления таблиц. В конце мне нужно запустить метод updateElasticCache. Если метод updateElasticCache терпит неудачу, я хотел бы откатить целые db-файлы.

Я не могу использовать (for { ... } yield()).transactionally этот код, потому что он не применим для моих случаев. Это «транзакционно» ждет действия db. Но я хочу добавить еще одну функциональность, которая не является db-процессом.

Возможно ли это? Как я могу это достичь?

ответ

3

DBIO.from

Да !!! его можно добавить нон логику дб между дб логики в пятне, используя DBIO действия состава и DBIO.from

Обратите внимание, что «свой материал» должен вернуться в будущем, будущее может быть преобразован в DBIO и могут быть составлены вместе с обычные действия db.

DBIO.from может помочь вам в этом. Вот как это работает. DBIO.from берет будущее и преобразует его в DBIOAction. теперь вы можете скомпоновать эти действия с обычными действиями db для выполнения операций не-db вместе с операциями db в транзакции.

def updateElasticCache: Future[Unit] = Future(doSomething()) 

теперь позволяет сказать, у нас есть некоторые БД действия

def createUser(user: User): DBIO[Int] = ??? 

хочу CreateUser откатить, если обновление кэша не удается. поэтому я сделать следующий

val action = createUser.flatMap { _ => DBIO.from(updateElasticCache()) }.transactionally 
db.run(action) 

теперь, если updateElasticCache терпит неудачу всего tx потерпит неудачу, и все будет откатить в нормальное состояние.

Пример

Вы можете использовать для понимания, чтобы сделать его хорошо выглядеть

def updateStats: DBIO[Int] = ??? 
val rollbackActions = 
    (for { 
    cStatus <- createUser() 
    uStatus <- updateStats() 
    result <- DBIO.from(updateElasticCache()) 
    } yield result).transactionally 
db.run(rollbackActions) 

все рулонных спины, если updateElasticCache будущее терпит неудачу

+0

Спасибо за ваш ответ. Я пытаюсь реорганизовать свои функции. Возвращаемый тип функции db-operation отличается от DBIO. Вместо DBIO [T] он возвращает JdbcProfile.this.DriverAction [Int, NoStream, Write]. ' def testUpdate (productId: Int, текст: String): JdbcProfile.this.DriverAction [Int, NoStream, Write] = { val q = для {p <- Продукты, если p.id === productId} yield (p.text) q.update (текст) } ' Извините, я только начал изучать Слик сегодня. Я не знаю, это логичный вопрос? – borney

+0

@sydboraa 'updateElasticCache()' должен возвращать 'Future [_]', а затем вы можете обернуть его в 'DBIO.from (updateElasticCache())'. или 'def updateElasticCache: DBIO [_] = DBIO.из {doSomething()} '' doSomething' в свою очередь возвращает 'Future [_]'. – pamu

+0

@sydboraa 'DBIO' - это псевдоним типа' DriverAction' – pamu

Смежные вопросы