Slick 3 Проверка транзакций на наличие ошибок Несколько действий

У меня есть вопросы о транзакциях Slick 3

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

Вот некоторый псевдо-код Slick:

val action = DBIO.seq(
  TableQuery[X].filter(_.x===a).delete,
  TableQuery[Y].filter(_.y===b).delete,
  TableQuery[Z].filter(_.z===c).delete
).transactionally

database.run(action)

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

Что такое идиома, чтобы сделать это в Slick?

Заранее спасибо Питер


person opus111    schedule 28.10.2015    source источник


Ответы (1)


Я нашел решение, которое работает для меня. Выкладываю сюда для тех, кто придет после.

Насколько я могу судить, похоже, что в SQL нет способа, чтобы DELETE WHERE завершилось ошибкой, когда предложение WHERE не соответствует ни одной строке. Однако INSERT, создающий дублирующую строку, может привести к сбою из-за ограничений таблицы.

Поэтому вместо того, чтобы просто УДАЛИТЬ строки, я добавляю в свои таблицы дополнительный столбец «Удалено». Удаление выглядит так

DELETE where ... and Deleted=0
INSERT ..., Deleted=1

и (повторная) ВСТАВКА выглядит так

DELETE where ... and Deleted=1
INSERT ..., Deleted=0

Теперь, если 2 процесса попытаются удалить одну и ту же строку, первый DELETE будет успешным для обоих, но INSERT завершится ошибкой с «дублирующейся строкой» для одного из них. Это исключение приведет к откату транзакции.

person opus111    schedule 30.10.2015