事务概述
一个事务时一个完整的逻辑单元,不可再分。
比如:银行账户转账,从A账户向B账户转钱
需要两条update语句
以上两条DML语句必须同时成功或者同时失败,不能出现一条成功,一条失败
要保证同时的成功和失败,需要使用事务机制
事务的存在就是为了保证数据的完整性
事务原理
案例:假设一个事务要进行运行insert,再执行update,然后delete,才算完成
事务机制:【开始】
执行:
执行 insert 语句,insert,,,(这个执行成功后,把执行记录到数据库历史操作中,并不会向文件中保存数据,不会真正修改数据
执行 update 语句,update,,,(执行后也是记录操作,不会真正修改)
执行 delete 语句,delete,,,(这个执行也是记录操作,【记录到缓存】不会真正修改数据)
提交事务或回滚(结束)
当全部执行结束后,全部同步到硬盘,清空历史缓存
TCL:
提交事务:commit
回滚:rollback
MySQL中的事务机制
MySQL是自动提交事务的
通过:
Start transaction 关闭自动提交
这样进行更改的时候,是不会将内容写入内存的,如果确认无误,可以使用 rolllback 进行回滚
事务特性
事务的四个特性:
原子性(Atomicity)【A】
- 整个事务中的所有操作,必须作为一个单元全部完成(或全部取消)。
- 事务是最小的工作单元,不可再分
- 整个事务中的所有操作,必须作为一个单元全部完成(或全部取消)。
一致性(Consistency)【C】
- 在事务开始之前与结束之后,数据库都保持一致状态。
- 保证多条DML语句必须同时成功或同时失败
- 在事务开始之前与结束之后,数据库都保持一致状态。
隔离性(Isolation)【I】
- 一个事务不会影响其他事务的运行。
持久性(Durability)【D】
- 在事务完成以后,该事务对数据库所作的更改将持久地保存在数据库之中,并不会被回滚
事务的隔离性
事务隔离性存在隔离级,理论上存在4个级别。
InnoDB 实现了四个隔离级别,用以控制事务所做的修改,并将修改通告至其它并发的事务:
- 读未提交(READ UMCOMMITTED)
允许一个事务可以看到其他事务未提交的修改。
读未提交存在脏读现象(Dirty Read),表示读到脏的数据【数据及其不稳定,数据不在硬盘中】
- 读已提交(READ COMMITTED)
允许一个事务只能看到其他事务已经提交的修改,未提交的修改是不可见的。
脏读现象解决了
读已提交存在的问题:不可重复读【不同时刻读到的数据不一样】
- 可重复读(REPEATABLE READ)
确保如果在一个事务中执行两次相同的SELECT语句,都能得到相同的结果,不管其他事务是否提交这些修改。(银行总账)
该隔离级别为InnoDB的缺省设置。
这种隔离级别解决了不可重复读的问题,只要运行一个事务,从开始到结束,都是一样的数据。
- 串行化(SERIALIZABLE)【序列化】
将一个事务与其他事务完全地隔离。
例:
A 可以开启事物,B 也可以开启事物
A 在事物中执行DML 语句时,未提交
B 不以执行 DML,DQL 语句
MySQL默认隔离级别:读已提交【三档】
Oracle默认隔离级别:可重复读
关闭自动提交:
start transaction;
设置隔离级别
演示两个事务,假如隔离级别
演示第1级别:读未提交
set global transaction isolation level read uncommitted;
演示第2级别:读已提交
set global transaction isolation level read committed;
演示第3级别:可重复读
set global transaction isolation level repeatable read;
查看隔离级别
服务器变量 tx_isolation(包括会话级和全局级两个变量)中保存着当前的会话隔离级别。
为了查看当前隔离级别,可访问 tx_isolation 变量:
查看会话级的当前隔离级别:
mysql> SELECT @@tx_isolation;
或:
mysql> SELECT @@session.tx_isolation;
查看全局级的当前隔离级别:
mysql> SELECT @@global.tx_isolation;