事物隔离级别

1.ACID

  1. **原子性:**一个事物包含多个对数据库的操作,这些操作要么都成功,要么都不成功
  2. **一致性:**数据从一个一致性状态到另一个一致性状态(转账 A500 B0)->(A300 B200) 总和500这个状态
  3. 持久性:事物提交后,持久化到DB中
  4. 隔离性 隔离级别(未提交读 、已提交读-、可重复读)
    A读取了B未提交的数据, 脏读
    A多次读取一条数据,B修改提交了那条数据后,A出现不可重复读
    A修改多条数据后,B又插入一条,A查到有一条未修改,幻读

2.数据库演示隔离性

2.1 默认隔离级别

查询数据库的默认的隔离性 =可重复读
在这里插入图片描述

2.2 读未提交
2.2.1 操作

– 设置为读未提交
set SESSION TRANSACTION isolation level read UNCOMMITTED;
start TRANSACTION; – 开始事物

session1session2
1.select * from tbl_kids_info where id =1; – 此时读取到的数据 age=111.select * from tbl_kids_info where id =1; – 此时读取到的数据 age=11
2.无操作2.update tbl_kids_info set age=12 where id=1;
3.select * from tbl_kids_info where id =1; – 此时读取到的数据 age=123.select * from tbl_kids_info where id =1; – 此时读取到的数据 age=12
2.2.2 结论

session1读到了session2未commit的数据,出现脏读

2.3 读已提交(解决脏读)
2.3.1 操作

show VARIABLES like ‘tx_isolation’;
– 设置为读已提交
set SESSION TRANSACTION isolation level read COMMITTED;
start TRANSACTION; – 开始事物

session1session2
1.select * from tbl_kids_info where id =1; – 此时读取到的数据 age=111.select * from tbl_kids_info where id =1; – 此时读取到的数据 age=11
2.无操作2.update tbl_kids_info set age=12 where id=1; commit;
3.select * from tbl_kids_info where id =1; – 此时读取到的数据 age=12
2.3.2 结论

session1只能读到session2提交后的数据,但是针对同一条数据两次读取的值不一样,即出现 不可重复读,另外如果在session2的第二部操作插入一条新数据,session1在3查出的数据多了一条,产生了幻读

2.4 可重复读
2.4.1 操作

show VARIABLES like ‘tx_isolation’;
– 设置为可重复读
set SESSION TRANSACTION isolation level REPEATABLE read;
start TRANSACTION;

session1session2
1. select * from tbl_kids_info where id =1; – 此时读取到的数据 age=111.select * from tbl_kids_info where id =1; – 此时读取到的数据 age=11
2.无操作2.update tbl_kids_info set age=12 where id=1;
3.无操作3.select * from tbl_kids_info where id =1; – 此时读取到的数据 age=12; 在执行commit
4.select * from tbl_kids_info where id =1; – 此时读取到的数据仍然 age=11
2.4.2 结论

session2即使执行commit,session1仍然看不到seesion2的操作数据的变更,原因大致为session1开始事物时,对所有数据进行了一个快照,他的所有操作都是在这个快照中完成的,所以session2的操作session1是看不到的
只是session2的更改不能及时让session1看到,或者对同一条数据更新,后提交的session会覆盖掉前一条的数据

– read REPEATABLE
– 读写锁
– 写操作 会阻塞其他事物的读或写
– 读与读共享,会阻塞其他的写(经测试,读锁会阻塞其他事物的写锁)

– read COMMITTED
– 读不阻塞其他事物的读 会阻塞写
– 写会阻塞其他事物的读写

数据库实现事务隔离的方式有两种:

一种是在读取数据前,对其加锁,阻止其他事务对数据进行修改,简称为MVCC。
另一种是不用加任何锁,通过一定机制生成一个数据请求时间点的一致性数据快照(Snapshot),并用这个快照来提供一定级别(语句级或事务级)的一致性读取,简称LBCC。

mysql每次对记录做修改都会记录到undo日志中,这样每一条记录就会形成一个链,
mvcc 解决的是 隔离级别下,对数据的并发操作查询不用通过锁机制

read UNCOMMITTED 直接读取链条最新的一条记录

read COMMITTED(每次select都会生成新的readView) 和 read REPEATABLE(第一次select生成ReadView,之后一直使用该快照)
先获得记录的undo日志链表 b
每次读取记录时,会查询当前该记录活跃的事物,根据事物id的大小形成一个表a ReadView快照,
使用b的记录,循环执行以下逻辑
如果b[i]id小于a表的最小id 该记录可以被读取(该记录已经提交)
如果b[i]id大于a表的最大id 该记录不可以被读取(该记录晚于a表的记录)
如果b[id]id介于之间
1)如果b[i]id在a表中,则说明b还在活跃状态,未提交 不可获取
2)如果b[i]id不在a表,可以读取

serializable 通过锁机制实现 事物串行

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值