举个栗子:
用户充值时要改变用户钱包总金额,以及添加充值记录
分析
start TRANSACTION
update user_balance set user_money=_user_money where user_id=_user_id;
insert into user_balancelog (user_id,user_money) values(_user_id,_user_money);
**#如果这边卡顿了一会,并且卡顿的同时有其它用户转账给该用户将发生灾难性事故 用select sleep(5);模拟**
commit;
解决方案 :
1.给表加锁 表锁? 行锁?
2.表锁分 read锁 以及 write锁
read锁进过分析还是无用 只能给整张表加写锁 但会大大减小效率
3.行锁 共享锁 以及 排它锁 (索引级别,上端sql为例 user_id必须为索引,不然还是会以表锁的形式加锁)
整合如下:
declare _money DECIMAL(10,2) DEFAULT 0; #局部变量
declare error bit DEFAULT false;
declare CONTINUE HANDLER for SQLEXCEPTION set error=true; #捕获错误信息
select user_money into _money from user_balance where user_id=_user_id for update;
set _user_moneys=_user_money+_money;
start TRANSACTION;
update user_balance set user_money=_user_moneys where user_id=_user_id;
insert into user_balancelog (user_id,user_money) values(_user_id,_user_money);
if error=true THEN
ROLLBACK; select ‘出错’ as result;
ELSE
commit;
select ‘重置完成’ as result;
end if;