Skip to content

事务概述

一个事务时一个完整的逻辑单元,不可再分。

​ 比如:银行账户转账,从A账户向B账户转钱

​ 需要两条update语句

​ 以上两条DML语句必须同时成功或者同时失败,不能出现一条成功,一条失败

要保证同时的成功和失败,需要使用事务机制

事务的存在就是为了保证数据的完整性

事务原理

案例:假设一个事务要进行运行insert,再执行update,然后delete,才算完成

​ 事务机制:【开始】

​ 执行:

​ 执行 insert 语句,insert,,,(这个执行成功后,把执行记录到数据库历史操作中,并不会向文件中保存数据,不会真正修改数据

​ 执行 update 语句,update,,,(执行后也是记录操作,不会真正修改)

​ 执行 delete 语句,delete,,,(这个执行也是记录操作,【记录到缓存】不会真正修改数据)

提交事务或回滚(结束)

当全部执行结束后,全部同步到硬盘,清空历史缓存

TCL:

​ 提交事务:commit

​ 回滚:rollback

MySQL中的事务机制

MySQL是自动提交事务的

通过:

sql
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默认隔离级别:可重复读

img

关闭自动提交:

sql
start transaction;

设置隔离级别

演示两个事务,假如隔离级别

演示第1级别:读未提交

sql
set global transaction isolation level read uncommitted;

演示第2级别:读已提交

sql
set global transaction isolation level read committed;

演示第3级别:可重复读

sql
set global transaction isolation level repeatable read;

查看隔离级别

服务器变量 tx_isolation(包括会话级和全局级两个变量)中保存着当前的会话隔离级别。

为了查看当前隔离级别,可访问 tx_isolation 变量:

查看会话级的当前隔离级别:

sql
mysql> SELECT @@tx_isolation;

或:

sql
mysql> SELECT @@session.tx_isolation;

查看全局级的当前隔离级别:

sql
mysql> SELECT @@global.tx_isolation;

本站除转载文章或特殊说明外,均遵循 CC BY-SA 4.0 协议发布。