概述
文章目录
- 5.数据库并发控制
- 5.6 事务的隔离级别
- 5.6.1 Read uncommitted(读未提交)
- 5.6.2 Read committed(读提交)
- 5.6.3 Repeatable read(重复读)
- 5.6.3.1 可重复读
- 5.6.3.2 出现幻读
- 5.6.4 Serializable(序列化)
5.数据库并发控制
5.6 事务的隔离级别
数据库事务的隔离级别有4种,由低到高分别为Read uncommitted 、Read committed 、Repeatable read 、Serializable。而且,在事务的并发操作中可能会出现脏读,不可重复读,幻读。
脏读 | 不可重复读 | 幻读 | |
---|---|---|---|
Read uncommitted(读未提交) | √ | √ | √ |
Read committed(读提交) | × | √ | √ |
Repeatable read(重复读) | × | × | √ |
Serializable(序列化) | × | × | × |
Serializable 性能最低,数据安全性最高;Read uncommitted 性能最高,数据安全性最差
-- 查看事务隔离级别
SELECT @@TRANSACTION_ISOLATION;
-- 设置事务隔离级别
-- SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE };
-- SESSION 是会话级别,表示只针对当前会话有效,GLOBAL 表示对所有会话有效
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
5.6.1 Read uncommitted(读未提交)
读未提交,就是一个事务可以读取另一个未提交事务的数据。
事例:张三的工资是15k,这个月发工资,财务不小心按错了数字,还没有来得及提交事务,就在这个时候,张三发现的工资变为了19k,张三以为涨工资了高兴的飞起,财务发现不对,回滚了事务,将工资改回了15k万元再提交。
分析:实际张三这个月的工资还是15k万,但是张三看到的是19k万。张三看到的是老板还没提交事务时的数据。这就是脏读。
时间 | 事务A | 事务B |
---|---|---|
T1 | 开启事务 | 开启事务 |
T2 | 查询得到的值为15k | 查询得到的值为15k |
T3 | 将15k改为19k | |
T4 | 查询得到的值为19k | |
T5 | 将19k改为15k | |
T6 | 查询得到的值为15k | |
T7 | 提交事务B | |
T8 | 查询得到的值为15k | |
T9 | 提交事务A |
读未提交演示
5.6.2 Read committed(读提交)
读提交,就是一个事务要等另一个事务提交后才能读取数据。
事例:张三的工资是15k,这个月发工资,财务给张三涨工资,将张三的工资改为19k,还没有来得及提交事务,就在这个时候,张三查询他的工资时还是15k,张三以为不给他涨工资了有点失落,财务提交了事务,然后张三不相信没有给他涨工资,就又查了一遍,发现他的工资涨到了19k。
分析:如果有事务对数据进行更新(UPDATE)操作时,读取数据事务要等待这个更新操作事务提交后才能读取数据,有效的避免脏读,但是一个事务进行了两次相同的查询而返回了不同的数据,这就是不可重复读。
时间 | 事务A | 事务B |
---|---|---|
T1 | 开始事务 | |
T2 | 查询得到的值为15k | 开始事务 |
T3 | 将15k改为19k | |
T4 | 事务提交 | |
T5 | 查询得到的值为19k | |
T6 | 事务提交 |
读提交,不可重复读
5.6.3 Repeatable read(重复读)
重复读,就是在开始读取数据(事务开启)时,不再允许修改操作。
事例:张三的工资是15k,这个月发工资,张三查询他的工资时是15k,财务给张三涨工资,将张三的工资改为19k,提交了事务,张三再次查询他的工资时还是15k,张三以为不给他涨工资了有点失落,提交了事务,然后张三不相信没有给他涨工资,就又查了一遍,发现他的工资涨到了19k。
分析:重复读可以解决不可重复读问题。写到这里,应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。
5.6.3.1 可重复读
时间 | 事务A | 事务B |
---|---|---|
T1 | 开始事务 | |
T2 | 查询得到的值为15k | 开始事务 |
T3 | 将值改为19k | |
T4 | 查询得到的值为15k | |
T5 | 提交事务 | |
T6 | 查询得到的值为15k | |
T7 | 提交事务 | |
T8 | 查询得到的值为19k |
可重复读
5.6.3.2 出现幻读
时间 | 事务A | 事务B |
---|---|---|
T1 | 开始事务 | |
T2 | 查询id为3的值是为空的 | 开始事务 |
T3 | 插入一行值,id为3 | |
T4 | 提交事务 | |
T5 | 查询id为3的值是为空的 | |
T6 | 插入一行值,id为3,报错,有id为3的 | |
T7 | 查询id为3的值是为空的 | |
T8 | 提交事务 |
幻读
5.6.4 Serializable(序列化)
Serializable是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
提醒:大多数数据库默认的事务隔离级别是Read committed(读提交),比如Sql Server , Oracle。Mysql的默认隔离级别是Repeatable read(重复读).
时间 | 事务A | 事务B |
---|---|---|
T1 | 开始事务 | 开始事务 |
T2 | 插入一行值,id为4 | |
T3 | 插入一行值,id为4,等待中,不能插入 | |
T4 | 提交事务 | 显示不能插入,因为有id为4了 |
T5 | 提交事务 |
最后
以上就是整齐月光为你收集整理的数据库并发控制、事务的隔离级别、由低到高分别为Read uncommitted读未提交、Read committed读提交、Repeatable read重复读、Serializable序列化5.数据库并发控制的全部内容,希望文章能够帮你解决数据库并发控制、事务的隔离级别、由低到高分别为Read uncommitted读未提交、Read committed读提交、Repeatable read重复读、Serializable序列化5.数据库并发控制所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复