Хороший улов параллелизма. Для этой цели выполняются транзакции базы данных .
Вы можете сделать это с помощью такой транзакции. (не отлажено)
BEGIN TRANSACTION;
SELECT SUM(amount) INTO @sum
FROM mytable
WHERE status IN (0,1)
AND recharge_date >= LAST_DAY(CURDATE()) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND recharge_date < LAST_DAY(CURDATE()) + INTERVAL 1 DAY
AND wallet_id = (((whatever))
FOR update;
UPDATE mytable SET status=2
WHERE status IN (0,1)
AND recharge_date >= LAST_DAY(CURDATE()) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND recharge_date < LAST_DAY(CURDATE()) + INTERVAL 1 DAY
AND wallet_id = (((whatever))
AND @sum > 1000;
/* then do your application logic, and come back and do */
UPDATE mytable SET status=(((whatever)))
WHERE status IN (0,1)
AND recharge_date >= LAST_DAY(CURDATE()) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND recharge_date < LAST_DAY(CURDATE()) + INTERVAL 1 DAY
AND wallet_id = (((whatever))
AND @sum > 1000;
/* finally, commit your transaction. */
COMMIT;
Обратите внимание, что все операторы SELECT...FOR UPDATE
и два UPDATE
имеют одинаковый оператор WHERE
. Это важно, потому что вы должны избегать обновления строк, которые вы не выбрали для обновления. Когда вы закончите, COMMIT
транзакции. Если вы решите, что не хотите продолжать в любое время после BEGIN TRANSACTION
, вы можете ROLLBACK
выполнить транзакцию и все в том состоянии, в котором они находились до того, как вы начали.
Этот шаблон
AND recharge_date >= LAST_DAY(CURDATE()) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND recharge_date < LAST_DAY(CURDATE()) + INTERVAL 1 DAY
- лучший способ выбрать даты в текущем календарном месяце. Это позволяет использовать индекс по столбцу для поиска соответствующих записей, где MONTH(recharge_date) = MONTH(CURDATE())
нет.
Я немного запутался в одном. Вы сказали, что вам нужно сделать СУММУ, которая указывает, что ваше изменение на status
затронет несколько записей в вашей таблице. Это действительно то, что вы хотите?