2015-05-24 4 views
2

В настоящее время я использую Slick 3.x.x, который полностью асинхронен во всех своих вызовах в базу данных. Скажем, у меня есть таблица, которая имеет какое-то управление версиями. Каждый раз, когда я создаю новую запись из уже существующей записи (т. Е. Обновляя данную запись), я должен убедиться, что я увеличиваю номер версии.Scala Асинхронные вызовы базы данных

Как я могу убедиться в этом асинхронном мире связи с базой данных, чтобы сохранить целостность данных? В моем случае с версией я сначала сделал бы выбор для максимальной версии, которая вернет мне будущее, а затем я буду использовать результат этого Будущего, приращение 1 и выпустить команду create!

Возможно, вполне возможно, что нить 1 началась с выбора максимальной версии и приостановлена ​​на некоторое время, поток 2, обслуживающий новый запрос, мог запустить выбор для максимальной версии и приращения и записать новую запись в базу данных. Теперь thread1 возвращается и пытается сделать тот же процесс, но только для того, чтобы thread1 мог перезаписать то, что написал thread2 в базе данных.

Возможно, у меня может быть несколько дубликатов, потому что порядок, в котором может выполняться несколько фьючерсов, может отличаться!

ответ

3

Асинхронность, с которой ваше приложение управляет взаимодействием с базой данных, не изменяет семантику транзакций базы данных. если вам нужны атомные последовательные последовательности операций, то вам нужна транзакция базы данных. Slick offers «комбинатор», называемый transactionally, который заставит последовательность операций работать в транзакции базы данных.

+0

Спасибо за указатель на «транзакционный». В documentatin я мог видеть, что есть предупреждение, которое выглядит следующим образом: «Предупреждение: - Отказ не гарантированно будет атомарным на уровне отдельного DBIOAction, который завернут транзакцией, поэтому вы не должны применять компиляторы восстановления ошибок в этот момент. Фактическая транзакция базы данных полностью создана и зафиксирована/откат для самых отдаленных транзакционных действий ». Я не мог полностью понять это. Может ли кто-нибудь объяснить? – sparkr

+0

предположим, что у вас есть несколько DBIOActions, позволяет называть их 'action1' и' action2'. Вы можете связать их вместе с 'action1 иThen action2'. Предположим, что вы сделали '(action1.transactionally andThen action2). Транзакциональная семантика семантической транзакции не гарантируется, что она будет поддерживаться, поэтому это может быть эквивалентно просто« (action1 andThen action2) .transactionally'. поэтому конструкция, подобная '(action1.transactionally.cleanUp (...) andThen action2) .transactionally', может не удалиться после откатов. '(action1 andThen action2) .transactionally.cleanUp (...)' будет их поймать. –

+0

Скажите, у меня есть (action1 andThen action2) .transactionally создает номер версии 2 для столбца в таблице, а другой поток, который выполняет тот же метод, который содержит мои два действия, будет видеть 2 или, возможно, 3 или даже 1 для номера версии? Поскольку результат (action1 andThen action2) .transactionally возвращает Будущее, как я могу гарантировать, что данные, увиденные другим Будущим, будут результатом его предыдущего Будущего? – sparkr

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