Использование транзакций Slick 3.0 при миграции из Squeryl - PullRequest
1 голос
/ 02 марта 2020

Я перевожу некоторый код Scala со Скверила на Слик. Все шло хорошо, пока я не наткнулся на топические транзакции. Squeryl сделал работу с транзакциями довольно простой: вам просто нужно обернуть свой код, будь то связанный с БД или нет, в блок transaction, и все готово.

Из примеров, которые я мог собрать в Интернете, Похоже, что ожидается реструктуризация всего проекта, чтобы он хорошо играл с его монадическим c подходом и с-для-пониманиями, чего я действительно хотел бы избежать.

Рассматривая произвольно кусок кода, такой как:

def f(): Unit = {
    UserRepository.getUser()
    ... some imperative code
    ServiceRepository.getServer()
    ...
    ServerRepository.updateServer(...)
    ...
    UserRepository.insertNewUser(...)
}

есть ли способ легко обернуть его в какой-нибудь транзакционный блок без необходимости изменения внутреннего логика c метода?

Спасибо

1 Ответ

0 голосов
/ 03 марта 2020

есть ли способ легко обернуть его в какой-нибудь транзакционный блок без необходимости изменения внутреннего логика c метода?

Короткий ответ - нет, но это зависит от того, что возвращают эти вызовы UserRepository и другие методы:

  • Если они равны Future[T] (или если вы заблокировали получение значения из будущего), вы Вы уже выполнили запрос, так что это нет, поскольку вы находитесь за пределами слоя Slick.

  • Если это действия (DBIO) или даже запросы, то это может быть изменение во внутреннем логике c: вам придется составлять действия вместе, но это возможно при смешивании в произвольном коде. Например, flatMap (или a для понимания) позволит это сделать.

В качестве примера смешивания логики c и составления действий вы можете написать код в виде строк:

val action = for {
  user <- UserRepository.getUser // a DBIO[User]
  result <- if user.notPermitted() {
      DBIO.failed(new IOException("Not allowed")
  } else {
      DBIO.successful(user)
  }  
} yield result

Введение методов и значений, которые работают в терминах DBIO (возможно, с использованием successful и failed), может сделать это преобразование менее болезненным для вас. Есть ответ, который может дать больше идей для смешивания логи c и действий: { ссылка }

Вам нужно выполнить последнее объединенное действие в .transcationally, чтобы убедиться, что все они действия выполняются в транзакции. Это описано в: https://scala-slick.org/doc/3.3.2/dbio.html#transactions

Есть две другие возможности, которые приходят на ум:

  • Вы могли бы реализовать свой собственный бэкэнд для Slick. Но это похоже на большую работу, и вы будете бороться с идеями в остальной части Slick до конца.

  • Хотя я бы обычно не рекомендовал это, более старая версия Slick (Slick 2) кажется ближе к SQueryl: https://scala-slick.org/doc/2.1.0/connection.html#session -обработка ... и это может дать вам ступеньку для Slick и затем для Slick 3 в качестве отдельной линии работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...