Столкнулся с проблемой при работе обновлении записей в БД postgresql
у меня есть два таблицы(products, baskets) в этом примере у меня есть массив id товаров, которые находятся в корзине, например [1,1,1,2,3], т.е. тут есть 3 одинаковых товара
но при удалении этой корзины, нужно увеличить количество товаров на 1, если у нас в этом примере 3 одинаковых товара, то в таблице products товар с id===1 нужно увеличить его свойство count на 1 если товар в корзине встречается только один раз, но у нас их 3 и след нужно увеличить значение count на 3.
так вот, при написании вот этого кода, у меня увеличивает значение не на 3 как нужно, а только на 1
await Promise.all(
products_array.map(async id => {
let product = await ProductModel.findOne({ where: {id}})
// находим продукт по id
let updatedProduct = await ProductModel.update({count: product.count+1}, {where: {id}})
// обновляем count продукта на 1
return updatedProduct
})
)
но при таком написании, все работает как и задумано
await Promise.all(
products_array.map(async id => {
return ProductModel.increment('count', { where: { id }});
})
)
так вот, как обновить свойство продукта первым способом и почему оно не работает, можете разъяснить в чем моя ошибка.
Ответы (1 шт):
Вы параллельно пытаетесь обновить одну и ту же запись БД и результат выполнения что первого, что второго "написания" зависит от случайных факторов. Ваш код, это - пример состояния гонки.
Лучшим решением будет заранее посчитать размер увеличения счётчика и выполнить (параллельно) редактирование записей с уникальными идентификаторами.
const products_array = [1,1,1,2,3];
const reducedProductsArray = products_array.reduce(
(acc, x) => {
acc[x] = (acc[x] || 0) + 1;
return acc;
},
{},
);
await Promise.all(
Object.entries(reducedProductsArray).map(
([id, val]) => ProductModel.increment({ count: val }, { where: { id }})
)
);
Пример вызова метода increment я взял тут, сам не пользуюсь sequelize, так что не могу проверить корректность.