У меня есть общий вопрос о том, как Slick/база данных управляет асинхронными операциями. Когда я составляю запрос или действие, скажем
(for {
users <- UserDAO.findUsersAction(usersInput.map(_.email))
addToInventoriesResult <- insertOrUpdate(inventoryInput, user)
deleteInventoryToUsersResult <- inventoresToUsers.filter(_.inventoryUuid === inventoryInput.uuid).delete if addToInventoriesResult == 1
addToInventoryToUsersResult <- inventoresToUsers ++= users.map(u => DBInventoryToUser(inventoryInput.uuid, u.uuid)) if addToInventoriesResult == 1
} yield(addToInventoriesResult)).transactionally
Есть ли вероятность того, что другой пользователь может, например, удалить пользователей сразу после выполнения первого действия UserDAO.findUsersAction(usersInput.map(_.email))
, но до остальных, так что вставка не удастся (из-за ошибки внешнего ключа)? Или сценарий, который может привести к потере обновления, например: транзакция A читает данные, затем транзакция B обновляет эти данные, затем транзакция A выполняет обновление на основе того, что она прочитала, она не увидит обновление B и перезапишет его.
Я думаю, что это, вероятно, зависит от реализации базы данных или, возможно, JDBC, поскольку это отправляется в базу данных в виде блока SQL, но, возможно, Slick играет в этом роль. Я использую MySQL.
Если здесь есть проблемы с синхронизацией, как лучше всего это решить? Я читал о таких подходах, как фоновая очередь, которая последовательно обрабатывает операции (как семантические единицы), но не устранит ли это частично преимущество возможности асинхронного доступа к базе данных -> плохая производительность?