в обновлении inventory
мы могли бы применить корректировку к значению, а не указывать заменяющее значение
(мы будем предполагать, что этот вопрос не относится к проблеме с INSERT дляtransaction_log
таблица; добавление строк в эту таблицу работает нормально. Предположим, что проблема связана с обновлением таблицы inventory
)
Мы будем предполагать, что столбец current_quantity
, на который есть ссылка в списке столбцов,количество из транзакции, а столбец quantity
, на который ссылается часть обновления, является рабочим значением.
В этом примере я буду ссылаться на них как на «корректировка» и «количество»".
Допустим, строка таблицы в настоящее время выглядит следующим образом:
item_id quantity_onhand quantity_adjust
------- --------------- ---------------
1 100 20
Текущий инвентарный запас равен 100, а последняя примененная корректировка - 20.
Допустим, нам нужно настроить quantity_onhand
на значение 10. Мы могли бы сделать что-то вроде этого:
INSERT INTO inventory (item_id, quantity_adjust) VALUES (1, 10)
ON DUPLICATE KEY
UPDATE quantity_onhand = quantity_onhand + VALUES(quantity_adjust)
, quantity_adjust = VALUES(quantity_adjust)
Предполагая, что item_id является первичным ключом (или уникальным ключом), нарушенным вставкой, wМы ожидаем, что результат будет:
item_id quantity_onhand quantity_adjust
------- --------------- ---------------
1 110 10
, т. е. 10 добавляется к количеству «вручную», а 10 сохраняется как последнее значение «корректировки».
Обратите внимание, что в части обновленияоператора VALUES()
возвращает значение, которое было бы вставлено, если бы вставка прошла успешно.
Результат фактически эквивалентен выполнению этого оператора:
UPDATE inventory
SET quantity_onhand = quantity_onhand + 10
, quantity_adjust = 10
WHERE item_id = 1
Потому чтооператор предоставляет только корректирующее значение, а не конкретное начальное значение, т. е. получает текущее значение запаса из самой строки, в то время как строка заблокирована оператором, тогда это обрабатывает проблему параллелизма с несколькими операторами, пытающимися заменитьсумма складских запасов.
Обратите внимание, что нам также нужно обработать случай, когда оператор INSERT
успешно выполняется, когда строка не существует. Мы могли бы определить столбец quantity_onhand
как `DEFAULT 0 (чтобы избежать сохранения значения NULL), тогда мы получили бы ноль, сохраненный в качестве суммы на руках, что, вероятно, не то, что мы хотим.