Mysql事务测试

登录mql命令行:
Cmd: mysql -uroot -p密码
【我的是512】

1、打开mysql命令行,将自动提交事务给关闭

–查看是否是自动提交 1表示开启,0表示关闭
select @@autocommit;
–设置关闭
set autocommit = 0;

2、环境和数据准备

–创建数据库
create database tran;
–切换数据库 两个窗口都执行
use tran;
–准备数据
create table psn(id int primary key,name varchar(10)) engine=innodb;
–插入数据
insert into psn values(1,’zhangsan’);
insert into psn values(2,’lisi’);
insert into psn values(3,’wangwu’);
commit;

3、测试事务

–事务包含四个隔离级别:从上往下隔离级别越来越高,意味着数据月亮越安全
read uncommitted;–读未提交
read committed;–读已提交
repeatable read;–可重复读
serializable;–序列化执行,串行执行
–产生数据不一致的情况:
脏读
不可重复读
幻读

隔离级别 异常情况
读未提交 脏读 不可重复读 幻读
读已提交 不可重复读 幻读
可重复读 幻读
序列化

4、测试1:脏读 read uncommitted

–两个窗口都要进行执行操作
–设置会话事务隔离级别为未提交读;
set session transaction isolation level read uncommitted;
start transaction; –开启事务

A:update psn set name=’’msb’;
A:select * from psn;
B:select * from psn; –此时读取的结果是msb,产生脏读。因为A事务并没有commit,读取到不存在数据
A:commit;
B:select * from psn; –此时读取的数据是msb,因为A事务已经commit,数据永久地被修改

5、测试2:当使用read committed 的时候,就不会出现脏读的情况了,但会出现不可重复读的问题

set session transaction isolation level read committed;
A:start transaction;
A:select * from psn;
B:start transaction;
B:select * from psn;
–执行到此处的时候发现,两个窗口读取的数据是一致的
A:update psn set name =’zhangsan’ where id = 1;
A:select * from psn;
B:select * from psn;
–执行到此处发现两个窗口读取的数据不一致,B窗口中读取不到更新的数据。【不会发生脏读】
A:commit;
A:select * from psn;–读取到更新的数据
B:select * from psn;–也读取到更新的数据
–发现同一个事务中多次读取数据出现不一致的情况【发生不可重复读】

6、测试3:当使用repeatable read的时候(按照上面的步骤操作),就不会出现不可重复读的问题,但是会出现幻读的问题

set session transaction isolation level repeatable read;
A:start transaction;
A:select * from psn;
B:start transaction;
B:select * from psn;
–此时两个窗口读取的数据是一致的
A:insert into psn values(4,’sisi’);
A:commit;
A:select * from psn;–读取到添加的数据
B:select * from psn;–读取不到添加的数据【不会发生不可重复读】
B:insert into psn values(4,’sisi’);–报错,无法插入数据
–此时发现读取不到数据,但是在插入的时候不允许插入,出现了幻读,设置更高级别的隔离级别即可解决

在同一个事务里面,不管你读了多少次数据,你的数据应该是一致的。

脏读:A只要一进行修改,还没有commit,B中查询结果就会跟着A变化(读取到不存在的数据)

不可重复读的问题:比如你在取钱,正在取的时候,有人给你转账(A进行了数据修改并且commit了),结果你这边马上显示钱变多了,这是不合理的。应该等你这次取钱操作结束后(也就是B当commit后),数据才会更新。

幻读:是在插入和删除数据的时候产生的,在查询的时候不会产生。查不到,但是存在。

总结
现在学习的是数据库级别的事务,需要掌握的就是事务的隔离级别和产生的数据不一致情况
后续学习声明式事务及事务的传播特性以及分布式事务。