我创建了一个网络应用程序,可让您向大学项目的其他人(如Paypal)汇款。
对于汇款网页,有一种表格,用户可以选择收款人的ID和汇款金额。
系统可以处理以下查询:
SET @moneytosend= ? ; //amount to send
START TRANSACTION;
UPDATE users SET balance= balance- @moneytosend WHERE id = ?; //sender's ID
UPDATE users SET balance= balance+ @moneytosend WHERE id = ?; //receiver's ID
COMMIT WORK;
问题是,当用户插入一个不存在的ID并且查询仍在执行时,有效地从发件人中删除了钱。
对于我的英语不完美,我们深表歉意,如果出现任何格式错误,请再次对不起。
答案 0 :(得分:1)
一种方法是检查update
查询中是否存在用户:
UPDATE users JOIN
(SELECT ? as sender_id, ? as receiver_id
) uu
ON u.id IN (uu.sender_id, uu.receiver_id)
SET balance = balance + (CASE WHEN u.id = uu.receiver_id THEN @moneytosend ELSE - @moneytosend)
WHERE EXISTS (SELECT 1 FROM users u2 WHERE u2.id = uu.sender_id) AND
EXISTS (SELECT 1 FROM users u2 WHERE u2.id = uu.receiver_id);
此逻辑将查询合并为一个查询,仍然只允许您输入两个参数。
答案 1 :(得分:1)
该问题是在第一条update语句中引起的,可以通过添加EXISTS
作为条件来解决:
update users
set balance = balance - @moneytosend
where
balance >= @moneytosend
and
id = ? <-- sender id
and
exists (
select 1 from (select * from users where id = ? <-- receiver id
) t);
请参见demo
正如雷蒙德·尼兰(Raymond Nijland)所建议的那样,请进行额外的检查,以使余额不会出现负值。