事务

1、定义

  • 关键词:Transaction
  • 一个最小的不可再分的工作单元
  • 通常一个事务对应一个完整的业务
  • 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务
  • 用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行
  • 用来管理DML(insert、update、delete)语句
  • 用于处理操作量大,复杂度高的数据

2、四大特征(ACID)

  • 原子性(A):事务是最小单元,不可再分
  • 一致性(C):事务要求所有的DML语句操作的时候,必须保证同时成功或者同时失败
  • 隔离性(I):事务A和事务B之间具有隔离性
  • 持久性(D):是事务的保证,事务终结的标志(内存的数据持久到硬盘文件中)

3、事务控制语句

// 开始事务
begin
start transaction

// 提交事务
commit

// 回滚事务
rollback

// 设置事务隔离级别
set transaction

// 设置提交模式
// 禁止自动提交
set autocommit = 0
// 开启自动提交
set autocommit = 1

注意:在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。

4、事务隔离级别

(1)读未提交:read uncommitted

  • 事物A和事物B,事物A未提交的数据,事物B可以读取到
  • 这里读取到的数据叫做“脏数据”
  • 这种隔离级别最低,这种级别一般是在理论上存在,数据库隔离级别一般都高于该级别

(2)读已提交:read commited

  • 事物A和事物B,事物A提交的数据,事物B才能读取到
  • 这种隔离级别高于读未提交
  • 换句话说,对方事物提交之后的数据,我当前事物才能读取到
  • 这种级别可以避免“脏数据”
  • 这种隔离级别会导致“不可重复读取”
  • Oracle默认隔离级别

(3)可重复读:repeatable read

  • 事务A和事务B,事务A提交之后的数据,事务B读取不到
  • 事务B是可重复读取数据
  • 这种隔离级别高于读已提交
  • 换句话说,对方提交之后的数据,我还是读取不到
  • 这种隔离级别可以避免“不可重复读取”,达到可重复读取
  • 比如1点和2点读到数据是同一个
  • MySQL默认级别
  • 虽然可以达到可重复读取,但是会导致“幻像读”

(4)串行化:serializable

  • 事务A和事务B,事务A在操作数据库时,事务B只能排队等待
  • 这种隔离级别很少使用,吞吐量太低,用户体验差
  • 这种级别可以避免“幻像读”,每一次读取的都是数据库中真实存在数据,事务A与事务B串行,而不并发

5、隔离级别与一致性关系

隔离级别 脏读取 不可重复读 幻象读
读未提交 可能 可能 可能
读已提交 不可能 可能 可能
可重复读 不可能 不可能 对InnoDB 不可能
串行化 不可能 不可能 不可能

6、查看事务隔离级别

// 查看当前会话事务隔离级别
select @@tx_isolation;

show variables like 'tx_isolation';

// 查看系统当前隔离级别
select @@global.tx_isolation;

show global variables like 'tx_isolation';

7、设置事务隔离级别

// 设置当前会话隔离级别
set session transaction isolatin level repeatable read;

// 设置系统当前隔离级别
set global transaction isolation level repeatable read;