Я создаю API, в котором можно увеличивать некоторые поля.
Заметив несоответствие данных в моей базе данных MySQL, я понял, что первая версия моего кода была глючной:
Answer.incrementVotesCount = async (id) => {
// get a copy of the data
let answer = await getAnswer(id);
// update the copy of the data locally
answer.votesCount++;
// replace the persisted data with the updated copy of the original data
await Answer.updateAll({id}, answer);
};
Получение некоторых данных, их локальное обновление и сохранение модификации могут вызвать проблемы согласованности, когда маршрут используется несколько раз за короткий промежуток времени.
Такая ситуация будет выглядеть примерно так:
- Звонящий А получает данные.Постоянное значение
votesCount
равно 14. - Абонент B получает данные.Постоянное значение
votesCount
равно 14. - Caller A обновляет данные.Постоянный
votesCount
становится 14 + 1. - В этот момент постоянный
votesCount
равняется 15, но копия его вызывающей стороны B по-прежнему равна 14. - вызывающая сторона B обновляет данные.Постоянное значение
votesCount
становится равным 14 + 1, тогда как оно должно составлять 15 + 1.
2 приращения были выполнены, но второе «раздавило» первое, поскольку оно увеличивает устаревшие данные..
Я думал об использовании нативной функциональности SQL LoopBack3, но кажется, что она не совсем надежна, поэтому я не уверен, стоит ли ее использовать (даже если запрос простпоскольку SET a = a + 1
, вероятно, должно работать правильно).
Я также думал об использовании триггеров MySQL для выполнения некоторого приращения, совместимого с ACID, но я не уверен, что могу найти чистый способ сделать это.
Какувеличить некоторые данные, не сделав их несовместимыми?