标签:
1.首先创建两个表,充值日志表(user_balance_log)、用户余额表(user_balance)
表结构如下:
(1)user_balance:
(2)user_balance_log:
注:log_type 日志类型1代表充值 2代表消费 3代表转账
2.写存储过程模拟用户充值
BEGIN
#Routine body goes here...
declare t_error int default 0;
declare usercount int default 0 ;
declare CONTINUE HANDLER for SQLEXCEPTION set t_error=1;#当发生错误时,设置为1
start TRANSACTION;
#插入用户充值日志表
insert into user_balance_log(user_id,log_type,log_des,log_value) values(_user_id,_log_type,_log_des,_log_value);
if ROW_COUNT()>0 then #插入成功
select count(*) into usercount from user_balance where user_id = _user_id;
if usercount > 0 then #用户存在
update user_balance set user_money=user_money+_log_value where user_id=_user_id;
else
insert into user_balance(user_id,user_money) values(_user_id,_log_value);
end if;
end if;
select sleep(7),‘卡顿结束‘;
if t_error=1 then
ROLLBACK;
else
COMMIT;
end if;
END
注:参数 IN _user_id int,IN _log_type tinyint,IN _log_des varchar(200),IN _log_value decimal(10,2)
3.执行存储过程
call sp_add_usermoney(3,1,‘用户充值‘,10);
执行5次之后,用户充值日志表(user_balance_log)如下,
用户余额表(user_balance)如下:也就是说,执行了五次存储过程,每次充值10元,累加5次就是50元。
4.模拟卡顿
在commit前模拟系统卡顿7秒,如下:
select sleep(7),‘卡顿结束‘;
执行一次存储过程,然后打开另外一个会话,执行
此时结果如下:
(1)用户充值日志表:
(2)用户余额表:
此时发现,用户余额表插入了同一个user_id的两行数据。因为系统卡顿后,存储过程中执行插入数据的操作并没有提交,而在另外一个会话中又插入了数据,这就产生了问题。
mysql颠覆实战学习记录 :用户充值功能实现(一):当服务器卡顿7秒发生了什么 11
标签:
原文地址:http://www.cnblogs.com/mumusan/p/5774874.html