ACID
ACID : 原子性 - 一致性 - 隔离性 - 持久性
四大特性
原子性: 事务将一组逻辑单元看成 一个操作 , 原子是最小单位不可再分割
一致性: 事务的前后 数据的应该保持一致
隔离性(isolation): 事务之间 彼此应该产生隔离, 隔离就会产生隔离问题 有问题就要解决
持久性: 事务不可逆 , 事务操作以后 不可再逆转(commit 之后 或者 rollback 事务销毁 不会再有了)
隔离问题
(至少有2个事务以上才会有隔离问题)
脏读: A一个事务 读到了另一个事务B没有提交的数据
不可重复读: 一个事务读到了另一个事务已经提交的数据 (数据之间已经干扰了) 泛指update
虚读/幻读: 一个事务读到了另一个新增的数据(数据库默认自己给处理了) 泛指 insert
解决方案(隔离级别)
四种解决方案:
1.读未提交: read uncommitted : 不解决任何问题 (不可能用)
2.读已提交: read committed : 解决脏读问题 , 有不可重复读和虚读的问题(oracle 的默认隔离级别)
3.可重复读: repeatable read : 解决脏读和不可重复读问题 , 有虚读问题 (mysql 默认的隔离级别)
4.串行化: serializable :(单线程 )解决所有问题 只有一个事务 (不可能用)
可以修改解决方案
安全级别 1< 2< 3< 4
性能角度 1>2>3>4
一般情况下使用数据库默认即可(现实开发中 追求 性能和安全并行 , 允许存在一定的误差 ,) 比如行锁 例如表锁
隔离级别的演示
修改隔离级别 :为了演示 隔离问题和隔离级别
global(全局) -> session (一次性当前会话有效 只在当前的黑窗口后效)
set global transaction isolation level 隔离级别; 修改隔离级别的代码
设置 全局 事务 隔离 级别 单词
set session transaction isolation level 隔离级别 ; 修改隔离级别的代码
设置 会话(当前的cmd窗口) 事务 隔离 级别 单词 (仅当前黑窗口有限 一次性的隔离级别)
脏读的问题
1.准备2个黑窗口 A窗口(左边-转账的人) B窗口(右边-查看的人)
2.必须调整隔离级别 如果隔离级别过高 演示不出来任何问题 read uncommitted
3.AB窗口必须同时开启事务
4.AB窗口同时查询数据库account表
5.A窗口正常操作 转出100 (A窗口不要提交事务)
6.B窗口查看账户看结果 -> 看到了A窗口没有提交的数据(脏读问题出现)
解决脏读问题
1.准备2个黑窗口 A窗口(左边-转账的人) B窗口(右边-查看的人)
2.必须调整隔离级别 如果隔离级别过高 演示不出来任何问题 read committed
3.AB窗口必须同时开启事务
4.AB窗口同时查询数据库account表
5.A窗口正常操作 转出100 (A窗口不要提交事务)
6.B窗口查看账户看结果 -> 看到原来的数据 解决了脏读问题
7.A窗口提交事务 B窗口 读到了A窗口已经提交的数据(不可重复读问题)
解决不可重复读问题
1.准备2个黑窗口 A窗口(左边-转账的人) B窗口(右边-查看的人)
2.必须调整隔离级别 如果隔离级别过高 演示不出来任何问题 repeatable read
3.AB窗口必须同时开启事务
4.AB窗口同时查询数据库account表
5.A窗口正常操作 转出100 (A窗口不要提交事务)
6.B窗口查看账户看结果 -> 看到原来的数据 解决了脏读问题
7.A窗口提交事务 B窗口 解决了不可重复读问题
serializable 串行化: 单线程(单事务)
1.准备2个黑窗口 A窗口(左边-转账的人) B窗口(右边-查看的人)
2.必须调整隔离级别 如果隔离级别过高 演示不出来任何问题 serializable
3.AB窗口必须同时开启事务
- AB 同时操作 -> 看结果