事务(Transaction)
事务概述
- 什么是事务?
- 一个事务是一个完整的业务逻辑单元,不可再分
- 如转账的两个update语句,要么同时成功,要么同时失败,需要使用DML中的"事务控制机制"
- 只有DML语句支持事务,其余语句,与事务无关
- insert delete update
- 为了保证数据的完整性,安全性
- 如果所有业务只需要一条DML语句,还需要事务机制么?
- 不需要。但是,实际上,一个业务,需要多条DML语句共同联合完成
事务原理
- 事务的提交和回滚都会让事务结束
- 提交 commit:将历史记录(缓存)真正同步到硬盘文件中,使数据真正发生修改,然后清除历史记录
- 回滚 rollback:不与硬盘文件发生关联,只是清除历史记录
事务的4大特性:ACID
-
A:原子性,事务是最小的工作单元,不可再分。
-
C:一致性,事务必须保证多条DML语句同时成功或者同时失败
-
I:隔离性,事务A和事务B之间相互隔离
- 4个隔离级别
-
D:持久性,最终数据必须持久化到硬盘文件中,事务才算成功完成
演示事务 : commit,rollback
-
mysql事务默认情况下是自动提交的
- 自动提交:只要执行任意一条DML语句,则提交一次
- 演示:insert... rollback 数据回不去了
- 自动提交:只要执行任意一条DML语句,则提交一次
-
如何关闭自动提交:start transaction;
- 演示:start transaction insert commit rollback 数据已经生效,回滚无效;
- 演示:start transaction insert rollback 数据成功回滚;
事务之间的隔离性
理论上隔离级别包括4个,实际上从2挡起步
- 第一级别:读未提交(read uncommitted)
- 可以读取到对方未提交的数据(数据在缓存里)
- 问题:存在脏读(Dirty Read)现象:表示读到了脏数据
- 可以读取到对方未提交的数据(数据在缓存里)
- 第二级别:读已提交(read committed)
- 可以读取到对方已经提交的数据
- 解决了脏读现象
- 问题:不可重复读(当对方不断修改数据时,哪怕自身事务并未提交,也无法读到与原先相同的数据)
- 可以读取到对方已经提交的数据
- 第三级别:可重复读(repeatable read)
- 解决了不可重复读问题
- 问题:读取到的数据是幻象(读到的是数据的备份)
- 第四级别:序列化读/串行化读
- 解决了上面所有问题
- 自身问题:效率低,需要事务间排队
- mysql和oracle的默认隔离性级别
- mysql:3级
- oracle:2级
两个事务演示隔离级别
-
演示1级别:read uncommitted
- 两个窗口进入mysql
- 设置事务的全局隔离级别:set global transaction isolation level read uncommitted;
- 查看事务的全局隔离级别:select @@global.tx isolation;
- 退出重新进入
- 2个窗口都开启事务
- 演示:read uncommitted
- 两个窗口进入mysql
-
演示2级别:read committed
-
两个窗口进入mysql
- 设置事务的全局隔离级别:set global transaction isolation level read committed;
- 查看事务的全局隔离级别:select @@global.tx isolation;
-
退出重新进入
-
2个窗口都开启事务
-
演示:read committed
-
-
演示3级别:repeatable read
-
两个窗口进入mysql
- 设置事务的全局隔离级别:set global transaction isolation level repeatable read;
- 查看事务的全局隔离级别:select @@global.tx isolation;
-
退出重新进入
-
2个窗口都开启事务
-
演示:repeatable read
- 查到的一直都是备份数据,不是原表数据,为幻象数据
-
-
演示4级别:序列化读
- 两个窗口进入mysql
- 设置事务的全局隔离级别:set global transaction isolation level serializable;
- 查看事务的全局隔离级别:select @@global.tx isolation;
- 退出重新进入
- 2个窗口都开启事务
- 演示:serializable
- 出现等待现象,占有数据的一方事务提交,等待方解除等待
- 两个窗口进入mysql
相关文章
暂无评论...