MySQL事务(四大特征)-存储过程

一:事务

1.四大特性(ACID)
    A:原子性
        每个事务都是不可分割的最小单位(同一个事务内的多个操作要么同时成功要么同时失败)
    C:一致性
        事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的
    I:隔离性
        事务与事务之间彼此不干扰
    D:持久性
        一个事务一旦提交,它对数据库中数据的改变就应该是永久性的
2.事物存在的必要性(真实比喻)
比如银行ATM机,转账功能比喻:

人物介绍:
小明
交通银行ATM机
小花

1.小明使用工行 通过交行ATM机给小花转账100元
2.交行向数据库发出请求,将小明的工行卡减去1000元。
3.数据库在向建设银行发出的请求,途中出现了信息错乱(断电\断网\不可抗力)出现了网络终断,导致请求没发出去

总结:
小明的钱减了,小花的钱没有加,导致信息错误(无法进行正常转账)

image

  • 解决方法:
    事务的必要性,就是(要么同时成功,要么同时失败)
3.如何使用事务
先介绍事物的三个关键字 再去用表实际展示效果
4.开启事务-回滚-确认
开启事务
start transaction;
回滚
rollback;
确认
commit;

二:事务案例实战

1.模拟消费
2.创建
create table user(
	id int primary key auto_increment,
	name char(32),
	balance int  # 存款
);
3.插入数据
insert into user(name,balance)
values
('jason',1000),
('tony',1000),
('oscar',1000);
4.开启事务
start transaction;
5.修改操作(同时事务)
update user set balance=900 where name='jason';  # 买支付
update user set balance=1010 where name='tony';  # 中介拿走10元
update user set balance=1090 where name='oscar';  # 卖家拿到90元
6.查询消费后的结果
select * from user;

image

7.但是在事物里边这个数据还没有到硬盘中,在内存中,还没有保存。
但是在事物里边这个数据还没有到硬盘中,在内存中,还没有保存。
现在这个状态还可以回退,我反悔了我不买了(双方同时失败)
回滚操作:rollback;

image

8.确认事物,确认支付成功不反悔(双方同时成功)
commit;

image

9.总结事物:
1.开启事务之后,只要没有执行commit操作,数据其实都没有真正刷新到硬盘。
2.开启事务检测操作是否完整,不完整主动滚回上一个状态,如果完整就应该执行commit操作。
10.使用python代码,来完善的伪代码的逻辑
try:  # 异常捕获(判断一旦以下代码出现一行报错则执行)
	update user set balance=900 where name='jason';  # 买家支付100元
	update user set balance=1010 where name='egon';  # 中介拿走10元
	update user set balance=1090 where name='tank';  # 卖家拿到90元
except 异常:  # 如果有异常就滚回去
	rolback;
else:  # 无异常则保存解释事务
	commit;

三:存储过程

1.什么是存储过程?
存储过程包含了一系列可执行的sql语句,存储过程存放于MySQL中,通过调用它的名字可以执行其内部的一堆sql,类似于python中的自定义函数。
2.存储过程格式
关键字: procedure
格式:
create procedure 函数名(参数)
begin
	功能体代码
end

调用其内部sql代码格式
call 函数名()
  • 类似于python中的自定义函数
3.无参存储过程
delimiter $$  # 修改结束符
create procedure p1()
begin
	select * from user;
end $$
delimiter ;  # 修改回来结束符

# 通过p1()调用其内部sql代码
call p1();

image

4.有参存储过程
delimiter $$
create procedure p2(
    in m int,  # in表示这个参数必须只能是传入不能被返回出去
    in n int,  
    out res int  # out表示这个参数可以被返回出去,还有一个inout表示即可以传入也可以被返回出去
)
begin
    select * from user where id > m and id < n;
    set res=0;  # 用来标志存储过程是否执行
end $$
delimiter ;


# 针对res需要提前定义
set @res=10;  # 定义/赋值  # 指定res=10
select @res;  # 查看
call p2(1,3,@res);  # 调用
select @res;  # 调用

image

5.查看存储过程-查看所有存储过程-删除存储过程
查看存储过程具体信息
show create procedure status;
查看所有存储过程
show procedure status;
删除存储过程
drop procedure pro2;
6.pyMySQL代码调用存储过程
import pymysql

# 创建链接
conn = pymysql.connect(
    host='127.0.0.1',
    port=3306,
    user='root',
    passwd='123',
    db='db6',
    charset='utf8',
    autocommit=True  # 涉及到增删改,二次确认
)

# 生成一个游标对象(操作数据库)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 调用存储过程固定语法callproc('p2',(1,3,10))
cursor.callproc('p2',(1,3,10))  # 内部原理 @_p1_0=1,@_p1_1=3,@_p1_2=10;
# 查看结果
print(cursor.fetchall())

image

四:隔离级别

1.事务隔离级别介绍
在SQL标准中定义了四种隔离级别,每一种级别都规定了一个事务中所做的修改
InnoDB支持所有隔离级别
set transaction isolation level 级别
2.read uncommitted(未提交读)
事务中的修改即使没有提交,对其他事务也都是可见的,事务可以读取未提交的数据,这一现象也称之为"脏读"
  • 解析:
    事务中数据修改即使没有提交,在内存中,没有提交到硬盘,别人可能也是引用的我内存中的数据,读的是修改的但是没有提交的,该现象称之为“脏读”
3.read committed(提交读)
大多数数据库系统默认的隔离级别
一个事务从开始直到提交之前所作的任何修改对其他事务都是不可见的,这种级别也叫做"不可重复读"
  • 解析:
    该事务修改了,只要没有提交,别人是不可读的,其他人用的就是没有改之前原表里面的数据,两者之间不会发生冲突,该现象称之为“不可重复读”
4.repeatable read(可重复读) # MySQL默认隔离级别
能够解决"脏读"问题,但是无法解决"幻读"
所谓幻读指的是当某个事务在读取某个范围内的记录时另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录会产生幻行,InnoDB和XtraDB通过多版本并发控制(MVCC)及间隙锁策略解决该问题
4.serializable(可串行读)
强制事务串行执行,很少使用该级别
一个个排队执行,效率太低,不可能使用
posted @ 2022-02-06 12:58  AlexEvans  阅读(130)  评论(0编辑  收藏  举报