Как увеличить некоторые данные с помощью LoopBack 3 без ущерба для согласованности? - PullRequest
0 голосов
/ 15 апреля 2019

Я создаю 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, но я не уверен, что могу найти чистый способ сделать это.

Какувеличить некоторые данные, не сделав их несовместимыми?

1 Ответ

0 голосов
/ 18 апреля 2019

Я бы забрал поле votesCount в отдельное отношение hasOne, а затем установил бы строгую модель Answer = 'фильтр', чтобы предотвратить сохранение данных, которые на самом деле не принадлежат модели. И когда будет принято решение о голосовании, я увеличу voteCount в этой отдельной модели, независимо от исходного Answer.

Если вы не хотите делать это так, вы можете попробовать проверить исходное значение в хуке before save, чтобы вы могли получить последнее значение из БД и сравнить значение votesCount из базы данных с значение в модели и обновите его соответственно.

...