mysql颠覆实战学习记录 :用户充值功能实现(一):当服务器卡顿7秒发生了什么 11

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的两行数据。因为系统卡顿后,存储过程中执行插入数据的操作并没有提交,而在另外一个会话中又插入了数据,这就产生了问题。

时间: 2025-01-01 16:06:54

mysql颠覆实战学习记录 :用户充值功能实现(一):当服务器卡顿7秒发生了什么 11的相关文章

mysql颠覆实战学习记录 :用户充值功能实现(二):钱的安全性之表锁 12

表锁分为read和write read锁: lock table 表名 read; unlock tabls; #解锁 当前会话只能读取数据,不能插入数据. 其他会话能读取数据,不能插入数据,解锁后数据插入. write锁: lock table 表名 write; 当前会话可以读书数据,可以插入数据: 其他会话,不能读取数据,也不能插入数据:

mysql颠覆实战笔记(三)-- 用户登录(二):保存用户操作日志的方法

版权声明:笔记整理者亡命小卒热爱自由,崇尚分享.但是本笔记源自www.jtthink.com(程序员在囧途)沈逸老师的<web级mysql颠覆实战课程 >.如需转载请尊重老师劳动,保留沈逸老师署名以及课程来源地址. 现在我们接着上节课,完成第二个功能,不管成功不成功都记录一个日志. 一.回顾上节课内容,我们在user_log表中添加一个字段 user_id.  在上一节课的存储过程新增一行代码,如下: BEGIN set @gid=0; set @user_name=''; set @_res

mysql颠覆实战笔记(二)-- 用户登录(一):唯一索引的妙用

版权声明:笔记整理者亡命小卒热爱自由,崇尚分享.但是本笔记源自www.jtthink.com(程序员在囧途)沈逸老师的<web级mysql颠覆实战课程 >.如需转载请尊重老师劳动,保留沈逸老师署名以及课程来源地址. 一.首先我们用上节课的存储过程对两张表压100万数据(各100万). 第一表 user_sys我们使用的是InnoDB模式,小卒自己的插入结果是: 第二张表 user_sys2我们使用的是MyISAM模式,小卒自己的插入结果是: 两个引擎的效率差异明显,所以我们再使用中根据实际情况

mysql颠覆实战笔记(四)--商品系统设计(一):商品主表设计

版权声明:笔记整理者亡命小卒热爱自由,崇尚分享.但是本笔记源自www.jtthink.com(程序员在囧途)沈逸老师的<web级mysql颠覆实战课程 >.如需转载请尊重老师劳动,保留沈逸老师署名以及课程来源地址. 这几节课沈老师先带我们说道一下商品表. 固定商品:譬如我们只是卖鞋,那么整个商品的属性基本都是一致的,列如鞋的颜色.尺寸.款式.品牌.价格.这时候我们涉及到的表往往是平面的. 这种涉及方法的特点: 1.纯定制化. 2.开发快,仅仅只要针对某些元素开发. 3.但是扩展性差,一旦我们新

mysql颠覆实战笔记(七)--白话理解事务

今天我们学习web开发级mysql颠覆实战课程第9课没MYSQL事务(一):白话理解事务.前面有两节课第7讲:商品系统设计(四):商品属性设计之自定义属性,第8讲:商品系统设计(五):一维属性的商品价格表设计的笔记本人省略,没有原因,个人爱好. 所谓事务,用老师白话理解就是: 1.不止要执行一个步骤.2.这些步骤每一步都按照既定想法去执行,错一步那么整个过程都反悔.3.事务进行时,外界干扰无法影响. 这算是老师的一个基础讲解,首先我们来建一张用户余额表,这个表我们采用的是Innodb模式,在这个

mysql颠覆实战笔记(五)--商品系统设计(二):定时更新商品总点击量

继续回到沈老师的MYSQL颠覆实战,首先回顾下上一节课的内容,请大家会看下上节课写的存储过程. 打开prod_clicklog表, 我们只要把日期(不含时分秒)的部分存在数据库中, 如果同一日期有相同用户点击商品,那么我们对其数值+1,否则的话,这张点击日志表会过于庞大 下面我们将prod_clicklog表修改下: 将字段clickdate 修改为 date类型,增加clicknum字段,默认为1. 然后,我们把上一节课的存储过程sp_load_prod再修改一下: BEGIN SELECT

mysql颠覆实战笔记(六)--商品系统设计(三):商品属性设计之固定属性

今天我们来讲一下商品属性 我们知道,不同类别的商品属性是不同的. 我们先建一个表prod_class_attr: 给这个表填入一些数据: 接下来,我们再建一个商品属性对应表 prod_attr 好了,下面我们把新增商品的流程撸一遍: 第一步,往商品主表插入数据 我们来新建一个存储过程 sp_new_prod: BEGIN INSERT INTO prod_main(prod_name,prod_classid) VALUES (_prod_name,_class_id); END 参数:IN _

linux 学习记录- 用户切换

一.用户切换:      缘由:1.使用一般账号操作系统,这是平日操作的好习惯.2.用较低权限启动系统服务:如apache软件,可以建立        apache用户来启动apache软件,如果这个程序被攻破,系统也不至于损毁.3.软件本身的限制. a.su  最简单的切换用户身份的方法       使用方法:  su [-lm][-c 指令][username]            详解: -:代表使用login-shell的变量档案读取方式来登入系统,若后面没有用户名,代表切换到root

【JavaEE企业应用实战学习记录】Filter

1 package sanglp.servlet; 2 3 import javax.servlet.*; 4 import javax.servlet.annotation.WebFilter; 5 import javax.servlet.http.HttpServletRequest; 6 import java.io.IOException; 7 8 /** 9 * Created by Administrator on 2016/10/5. 10 */ 11 @WebFilter(fi