事务隔离级别

事务隔离级的意义:
数据库是一个多用户的共享资源, MySQL允许多线程并发访问用户可以通过不同的线程执行不同的事务。为了保证这些事务之间不受影响,对事务设置隔离级是十分必要的。
1.查看隔离级别

#1.查看全局隔离级
Select @@global.transaction_isolation;
#2.查看当前会话中的隔离级
Select @@session.transaction_isolation;
#3.查看下一个事务的隔离级
Select @@transaction_isolation;

全局的隔离级:影响所有连接 MYSQL用户.
当前会话隔离级:只影响当前正在登录 MySQL服务器的用户.(不会影响其他用户)
下一个事务的隔离级:仅对当前用户的下一个事务操作有影响.

默认情况下3种方式的结果都是REPEATABLE—RED:

Select @@transaction_isolation;

在这里插入图片描述
2.修改隔离级别
设置事务的隔离级别:
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL 参数值
SESSION:当前会话
GLOBAL:全局
TRANSACTION:事务
ISOLATION:隔离
LEVEL:级别
直接省略:下一个事务的隔离级

使用演示:修改为READ UNCOMMITTED:

#修改事务隔离级别
Set Session Transaction Isolation Level 
Read Uncommitted;
#查看是否修改成功
Select @@transaction_isolation;

在这里插入图片描述
使用演示:修改为REPEATABLE READ:

#修改事务隔离级别
Set Session Transaction Isolation Level
 Repeatable Read;
#查看是否修改成功
Select @@transaction_isolation;

在这里插入图片描述
3.MySQL中事务的隔离级别

  • REPEATABLE-READ:可重复读
    MYSQL的默认事务隔离级,它解决了脏读和不可重复读的问题确保了同一事务的多个实例在并发读取数据时,会看到同样的结果.
    该级别理论上会出现幻读( PHANTOM READ)问题.
    幻读又被称为虚读,是指在一个事务内两次查询中数据条数不一致,
    情景模拟:在网站后台统计所有用户的总金额时
    当前只有两个用户,总金额为2000元,此时新增一个用户,并且存入1000元再次统计会发现总金额变为3000元,造成了幻读的情况.
#通过READ COMMITTED演示幻读问题
#客户端B
Set Session Transaction Isolation Level 
Read Committed;
Start Transaction;
Select Sum(money) From sh_user;
#客户端A新增一个用户,客户端B就会幻读
#客户端A
Insert Into sh_user(id,name,money) 
Values(3,'Tom',1000);
#客户端B
Select Sum(money) From sh_user;
#实验结束,提交事务
Commit;
#利用REPEATABLE READ避免幻读
#客户端B
Set Session Transaction Isolation Level
 Repeatable Read;
Start Transaction;
Select Sum(money) From sh_user;
#客户端A新增一个用户,客户端B没有幻读
#客户端A
Insert Into sh_user(id,name,money) Values (4,"d",1000);
#客户端B
Select Sum(money) From sh_user;
#实验结束,提交事务
#客户端B
Commit;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • READ UNCOMMITTED:读取未提交
    事务中最低的级别,可以读取到其他事务中未提交的数据.也称为脏读( Dirty Read):一个事务读取了另外一个事务未提交的数据。
    情景模拟:Aex给Bill转账100元购买商品.
    Aex开启事务后转账,但不提交事务,通知Bill来查询
    如果B的隔离级别较低,就会读取到Alex的事务中未提交的数据发现Aex确实给自己转了100元,就给Aex发货.
    等B发货成功后,Aex将事务回滚,B就会受到损失.

设置客户端B的隔离级别,允许脏读:

#设置客户端B的隔离级别,允许脏读
#客户端B
Set Session Transaction Isolation Level 
Read Uncommitted;
#在客户端B中查询Bill当前的金额
#客户端B
Select name,money From sh_user Where name="Bill";
#客户端A开启事务并转账
#客户端A
Start Transaction;
Update sh_user Set money=money - 100 
Where name ="Alex";
Update sh_user Set money=money + 100
 Where name ="Bill";
#客户端A未提交事务,客户端B查询余额
#客户端B
Select name,money From sh_user 
Where name="Bill";--读到了未提交的数据
#提高隔离级别,解决脏读问题
#客户端B
Set Session Transaction Isolation Level 
Read Committed;
Select name,money From sh_user Where name="Bill"
#实验结束,回滚客户端A的事务
#客户端A
Rollback;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • READ COMMITTED:读取提交
    大多数DBMS(如 SQL Server、 Oracle)的默认隔离级,但不包括MYSQL
    只能读取其他事务已经提交的数据,避免了脏读问题.
    但是会出现不可重复读( NON-REPEATABLE READ)问题.
    不可重复读:一个事务中多次查询的结果不一致,原因是查询的过程中数据发生了改变.
    情景模拟:在网站后台统计所有用户的总金额.
    第1次查询Alex有900元,第2次查询Alex有800元.
    问题:在同一个事务中,同样的两次查询结果不同
    原因:第2次查询前Alex取出了100元.

设置隔离级别,查询Alex的金额:

#设置隔离级别,查询Alex的金额
#客户端B
Set Session Transaction Isolation Level
 Read Committed;
Start Transaction;
Select name,money From sh_user 
Where name="Alex";
#Alex取出100元,再次查询Alex金额
#客户端A
Update sh_user Set money=money - 100 
Where name ="Alex";
#客户端B
Select name,money From sh_user Where name="Alex"
#实验结束,提交事务
#客户端B
COMMIT;
#更改隔离级别,避免客户端B的不可重复读
#客户端B
Set Session Transaction Isolation Level 
Repeatable Read;
Start Transaction;
Select name,money From sh_user Where name="Alex"
#更改Alex的金额,客户端B两次查询的结果一致
#客户端A
Update sh_user Set money=money + 100
 Where name ="Alex";
#客户端B
Select name,money From sh_user Where name="Alex"
#实验结束,提交事务
#客户端B
Commit;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • SERIALIZABLE:可串行化
    隔离级的最高级别,它在每个读的数据行上加锁,使之不会发生冲突,解决了脏读丶不可重复读和幻读的问题.
    由于加锁可能导致超时( Timeout)和锁竟争( Lock Contention)现象,性能是4种隔离级中最低的.
    除非为了数据的稳定性,需要强制减少并发的情况时,才会选择此种隔离级
#Serializable(可串行化)
#演示Serializable
#客户端B
Set Session Transaction Isolation Level
Serializable;
Start Transaction;
#客户端B开启事务后查询数据,此时会锁表
#客户端B
Select name,money From sh_user Where name="Alex"
#客户端A无法立即写入,等待表解锁
#客户端A
Update sh_user Set money=money+100 
Where name="Alex";
#客户端B提交事务后,客户端A才可以写入成功
#客户端B
commit;
#锁等待超时默认为50秒,可进行修改
Select @@innodb_lock_wait_timeout;

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值