今天财务在后台手工充值的时候, 由于系统反应慢, 点了两次, 结果是流水记了两笔, 金额只增加了一笔
今天用开两个SQLyog客户端来还原财务充值发生的情况, 以下SQL在多线程下执行, 将会出现写覆盖。
如果只执行select amount from t_test where id=91是不加任何锁的,因此在update提加之前, 这条语句也能执行。
BEGIN;
SELECT @a:=amount FROM t_test WHERE id = 91; (两条线程同时执行到了这儿)
-- SELECT @a:=amount FROM t_test WHERE id = 91 for update; (两条线程同时卡在这儿, 这时状况发生了, 估计是有另外一个比较大的事务里面锁住了这行记录)
SET @a=@a+10;
SELECT @n:=@a;
UPDATE t_test SET amount = @a WHERE id = 91;
SELECT @a:=amount FROM t_test WHERE id = 91;
COMMIT;
ROLLBACK;
解决方案, 用乐观锁, 如果发现amount已经更改, 则提示修改不成功
update t_test set amount = amount + 10 where id =91 and amount = @originalAmount.