Для обратной совместимости в моем приложении я создаю новые модели «на лету» при первом запросе.
Псевдокод:
let results = await Model.findAll({ where });
if(results.length === 0) {
await Model.bulkInsertDefaults();
results = Model.findAll({ where });
}
return results;
Проблема заключается в параллелизме. Если два пользователя обращаются к запросу одновременно, я получаю повторяющиеся значения. Я попытался реализовать транзакцию:
try {
let transaction = await sequelize.transaction()
let results = await Model.findAll({ where, transaction });
if(results.length === 0) {
await Model.bulkInsertDefaults(transaction);
results = Model.findAll({ where, transaction });
}
await transaction.commit();
return results;
} catch(e) {
await transaction.rollback();
}
Что, похоже, не помогло.
Таким образом, я просто добавил UNIQUE INDEX
в свою таблицу:
CREATE UNIQUE INDEX idx_p_title_p_id ON p(title, p_id)
Который должен сделать второй одновременный возврат запроса. Это далеко не идеально, но этого вполне достаточно.
Есть ли лучший способ справиться с этой ситуацией с помощью какой-то блокировки? Чтобы второй запрос повторял попытку, пока не будет выполнена первая транзакция?