mysql--事务隔离机制(保姆级)

一、mysql中事务特性以及隔离机制(选做)
ACID
脏读,不可重复读,幻读
不同隔离级别解决什么问题(实际操作验证)


①脏读

1.创建数据库test以及表rooms

2.先开一个mysql客户端(也可以说是命令行),使用use test;启用test数据库,再使用set session transaction isolation level read COMMITTED;

3.使用这个数据库,再设置事务的隔离级别为读未提交,最后使用select语句进行一次查询操作,方便后面的对照

(1)使用这个数据库

use test;

(2)设置事务的隔离级别
set session transaction isolation level read UNCOMMITTED;

查看数据库的隔离级别

select @@transaction_isolation;

结果:

 创建表格rooms:

create table rooms(
     id int(3) not null,
     tenant_id int(3) default null,
     rent int(5) default null,
     primary key(id) using btree
     )engine = InnoDB character set =latin1 collate = latin1_swedish_ci row_format =dynamic;

 向表格rooms中插入数据:

insert into rooms values (120,1,1000);


insert into rooms values (123,2,222);

 4.开启另一个mysql命令行,尝试更新一下数据(但不提交,如果要提交 最后一行加入 commit指令)

begin; // 这个语句开启一个事务

update rooms set id = 1 where id = 120;

在update所在的事务没有提交(使用commit指令提交)的情况下使用select语句

select * from rooms

 结果(因为事务的隔离级别为 读未提交 ,所以读取到了update事务未提交的内容):

 ②不可重复读:

在继续沿用rooms表的情况下,

1.先开一个mysql客户端(也可以说是命令行),使用use test;启用test数据库,再使用set session transaction isolation level read COMMITTED; 命令设置数据库事务的隔离级
别为 读已提交(因为数据库的默认隔离级别为可重复读)

2.开启事务,使用start transaction;或者begin;命令

3.使用select * from rooms; 查询数据库中的数据

查询结果如下:

4.接着再开一个命令行,使用 update rooms set rent = 1100 where id = 120; 将房间号为120的房租改为1100;注意这个命令行中,我们不用设置手动开启或者关闭一个事务,mysql默认会为我们提交这个更新事务。

update rooms set rent = 1100 where id = 120; 

5.在第一个命令行中,使用select * from rooms; 查询数据库中的数据(注意这个时刻,第一个命令行中的事务还处于待提交状态,因为没有使用commit;命令)。

select *from rooms;

查询结果:查询到了update事务提交后的数据,由此造成了不可重复读的问题

 

 ③幻读:

1.开启第一个mysql客户端,启用test数据库,使用数据库默认的隔离级别(可重复读)。代码如下:

begin;
set session transaction isolation level read COMMITTED;
update rooms set rent = 1188 where id = 120;

2.在第一个客户端中使用begin;命令开启事务,并且执行select * from rooms; 操作,但不提交
结果如下

3.开启第二个mysql客户端,在第二个客户端中执行insert into rooms (id, tenant_id, rent) values (124, 5, 600);语句
4.在第一个客户端中 再次执行 select * from rooms; 操作,查到的结果和第2步中的一样,因为在 "可重复读"的隔离级别下,使用的是快照读,读取的都是第一次select的数据


5.这里如果我们把快照读改为当前读,即执行select * from rooms for update;每次读取的都是最近更新的数据

6.即便此时我们不使用当前读,而使用快照读,直接执行更新操作,更新sql会将符合条件的由其他事务提交的最新数据都会更新,这也是幻读带来的影响(因为更新事务会先扫描全表查询数据,然后将得到的数据拿回内存,对内存中的数据进行修改)

(1)在快照读的情况下执行更新操作

update rooms set rent = rent - 200 where rent > 200 and id < 125;

(2)执行快照读select 操作

select *from rooms;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值