Работали ли вы с транзакциями в Room
Что проверяют
Понимаете ли вы, что Room это обёртка над SQLite, и различаете ли случаи, когда атомарность действительно нужна. Заодно смотрят, знаете ли вы, чем транзакция опасна: она держит блокировку, и всё лишнее, сделанное внутри неё, тормозит остальное приложение.
Как отвечать
Аннотация @Transaction над методом DAO оборачивает все вызовы внутри него в одну транзакцию: либо применяется всё, либо ничего. Исключение внутри означает откат, отдельно вызывать откат не нужно. Когда операции лежат в разных DAO, удобнее обёртка на уровне базы:
db.withTransaction {
orderDao.insert(order)
itemDao.insertAll(items)
cartDao.clear(userId)
}Второе применение той же аннотации не про атомарность записи, а про чтение: метод, возвращающий сущность с @Relation, выполняется несколькими запросами, и без транзакции между ними данные могут разъехаться.
Стоит сказать и про скорость: вставка тысячи записей по одной это тысяча транзакций и тысяча обращений к диску, тот же объём одним пакетом внутри одной транзакции быстрее на порядок.
Где спотыкаются
Гасят исключение внутри транзакции. Если catch внутри блока проглотил ошибку и метод завершился нормально, отката не будет: Room посчитает работу успешной и зафиксирует то, что успело записаться. Чтобы откатить, исключение надо пробросить наружу.
Делают внутри транзакции сетевой запрос. Пока идёт ожидание ответа, база заблокирована, остальные обращения стоят в очереди и упираются в таймаут. Данные получают до начала транзакции, внутри остаётся только запись.
Ставят аннотацию на метод с единственным запросом и считают, что защитились от гонок. Один оператор и так атомарен, смысл появляется там, где шагов несколько и промежуточное состояние недопустимо.