事务 TRANSACTION
什么是事务?
一个事务就是一个完整的业务逻辑 -- 划分一个最小的业务单元,整个操作同时完成同时失败
只有 DML语句 - INSERT、DELETE、UPDATE 才会涉及事务
为什么使用事物?
业务需要多条 SQL - DML语句才能完成,确保这些语句同时完成或失败,保证数据一致性
事务的原理,如何实现多条语句同时成功或失败?
在事物的执行过程中,每一条 DML语句操作都会记录到 “事务性活动的日志文件” 中
在事物的执行过程中,即可以提交事务,也可以回滚事务
-
提交事务
- 事务开启后,执行DML语句,最后成功时提交事物,标志事务成功结束
-
回滚事务
- 将事务开启后所有执行的DML语句全部撤销,并清空事务性活动的日志文件 = 事务以失败结束
- 回滚事务,标志事务全部失败的结束
如何提交事物与回滚事务?
提交事务
-
COMMIT;
-
MySQL默认情况下,支持自动提交事务
回滚事务
-
ROLLBACK;
-
回滚永远只能提交到上一次的提交点
关闭自动提交事务 -- 手动开启一个需要手动提交\回滚的事务
-
START TRANSCTION;
-
事务中,DML语句不直接修改数据库中的数据 -- 不记录在数据库对应表的存储文件中
-
但能够查询到全部记录,包括事务中还未存入表的记录 -- 查询会读取事务性活动的日志文件的内容
-
COMMIT 和 ROLLBACK 都会结束事务
事务 4 特性 ACID
- A:原子性
- 事务是最小工作单元,不可再分
- C:一致性
- 一个事务的所有操作必须同时成功、同时失败
- I:隔离性
- 不同事务操作同一张表,需要设置隔离级别
- D:持久性
- 事务提交,将没有保存到硬盘的数据保存到硬盘上,实现数据持久化
事物的隔离性
隔离级别
//设置隔离级别 -- 需要新建查询
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
//查看隔离级别
SELECT @@tx_isolation;
- 读未提交:read uncommitted (最低级别) 事务B提交前事务A就能读到
- 事务A可以读取到事物B未提交的数据
- 存在问题:脏读现象 Dirty Read,事务B可能将未提交的数据回滚,数据在事物A中为脏数据
- 这种隔离级别一般存在于理论上,实际不使用
- 读已提交:read committed 事务B提交后事务A才能读到
- 事务A只能读取到事务B已经提交的数据
- 解决脏读现象
- 新问题:不可重复读取数据,事务A两次读取数据可能不一致,因为期间有其他事务修改数据库
- 在实际使用中常用,是Oracle数据库默认的隔离级别
- 可重复读:repeatable read 事务B提交之后事务A也读不到
- 事务A开启后,无论多久,每次读取数据都是一致的,其他事务对数据库的修改不影响事务A
- 解决不可重复读取数据的问题
- 新问题:每一次读取数据可能是幻象(开启事务时的备份),不够真实
- 是MySQL数据库默认的隔离级别 ,也是银行总账读取数据时的隔离级别
- 序列化/串行化:serializable (最高级别)
- 事务间不能并行,一次执行一个事务
- 解决所有问题,但效率最低