I locked the table using FOR UPDATE with an IF validation. However, it seems that they aren't able to handle the parallel request?
I have two samples of stored procedures. I tested these using cURL to make a parallel requests.
DROP PROCEDURE IF EXISTS SAMPLE;
DELIMITER //
CREATE PROCEDURE SAMPLE(_quantity INT)
BEGIN
DECLARE _total INT DEFAULT 0;
SELECT COALESCE(SUM(price),0) + _quantity INTO _total FROM account FOR UPDATE;
IF(_total <= 50) THEN
CALL SAMPLE2(_quantity);
ELSE
SELECT 'EXCEEDED';
END IF;
END; //
DELIMITER ;
DROP PROCEDURE SAMPLE2;
DELIMITER //
CREATE PROCEDURE SAMPLE2(_quantity INT)
BEGIN
INSERT INTO account(price) VALUES(_quantity);
END; //
DELIMITER ;
I expect the output to not exceed 50 based on my validation.
LOG OUTPUT:
CALL SAMPLE(?) [ [ RowDataPacket { _total: 20, _quantity: 20, 'now()': 2019-07-22T08:33:27.000Z } ],
CALL SAMPLE(?) [ [ RowDataPacket { _total: 20, _quantity: 20, 'now()': 2019-07-22T08:33:27.000Z } ],
CALL SAMPLE(?) [ [ RowDataPacket { _total: 40, _quantity: 20, 'now()': 2019-07-22T08:33:27.000Z } ],
CALL SAMPLE(?) [ [ RowDataPacket { _total: 80, _quantity: 20, 'now()': 2019-07-22T08:33:28.000Z } ],
[ RowDataPacket { EXCEEDED: 'EXCEEDED' } ],
CALL SAMPLE(?) [ [ RowDataPacket { _total: 80, _quantity: 20, 'now()': 2019-07-22T08:33:28.000Z } ],
[ RowDataPacket { EXCEEDED: 'EXCEEDED' } ],
CALL SAMPLE(?) [ [ RowDataPacket { _total: 80, _quantity: 20, 'now()': 2019-07-22T08:33:28.000Z } ],
[ RowDataPacket { EXCEEDED: 'EXCEEDED' } ],
On the second call, it seems that they didn't read the inserted value.
Data Inserted.
+----+-------+---------------------+
| id | price | created |
+----+-------+---------------------+
| 1 | 20 | 2019-07-25 13:44:51 |
| 2 | 20 | 2019-07-25 13:44:51 |
| 3 | 20 | 2019-07-25 13:44:51 |
+----+-------+---------------------+
What I need is the summation of price <= 50. But the above output showed 60.