事务Transaction

1. 概念

  • 一个最小的不可再分的工作单元
  • 一个事务对应一个完整的业务逻辑
  • 事务只和DML语句有关系,由批量的DML语句组成

2. 事务的四个特性(ACID)

  • Atomicity(原子性):事务是不可分割的。内部操作要么全成功,要么全失败。

  • Consistency(一致性):事务要求所有DML语句操作,必须保持同时成功或同时失败.

  • Isolation(隔离性):多个并发事务之间要相互隔离,不能有干扰。

  • Durability(持久性):事务一旦提交就会持久化数据(写入数据库并持久储存),并且不能回滚。

2.1. 原子性

确保原子性的方法是回滚。在MySQL中,回滚是通过回滚日志(Undo Log)实现的。回滚日志就是记录了你的多有操作的逆操作,当需要回滚时,就把这个事务的回滚日志里的操作全执行一次。

2.2. 一致性

事务执行的前后都是合法的数据状态,不会违背任何的数据完整性,这就是“一致”的意思。即在事务执行前后数据都应是正确无误,逻辑自洽,完整无缺的。

3. 隔离级别

3.1. read uncommitted(读未提交)

事务A先写数据,则事务B不允许同时进行写操作,但允许事务B读A未提交的此行数据,这里读到的数据称为脏数据,即脏读"Dirty Read"

底层:读不加锁,写加行级共享锁(可以读,无法修改和删除的一种数据锁,只能加共享锁)直到事务结束

3.2. read committed(读已提交)

事务A先写,事务B不能读,A提交后才能读此行数据

但可能出现不可重复读:即B前后两次读之间A修改了,导致不一致

底层:读时加行级共享锁,读完释放,写时加行级排它锁(不能加其他锁,获锁的事务可以读写)直到事务结束

3.3. repeatable read(可重复读)

事务A先写,事务B不能读写,A先读,B不能写

但可能产生幻读:即B前后两次读全表之间A插入了,导致不一致

底层:读时加行级共享锁,直到事务结束,写时加行级排他锁直到事务结束.

3.4. serializable(可串行化)

事务只能一个按顺序一个执行

底层:读时,加表级共享锁,直到事务结束,写时加表级排他锁直到事务结束.

隔离级别 脏读(Dirty read) 不可重复读(Non-repeatable read) 幻读(Phantom read) 第一类丢失更新 第二类丢失更新
READ UNCOMMITED 允许 允许 允许 不允许 允许
READ COMMITED 不允许 允许 允许 不允许 允许
REPEATABLE READ 不允许 不允许 允许 不允许 不允许
SERIALIZBLE 不允许 不允许 不允许 不允许 不允许
  • 脏读:读取缓冲池中未提交的行数据就叫脏读,违反了事务的隔离性。

  • 不可重复读:一个事务内,多次读到了其他已经提交的事务的更改(或删除)数据.对策:添加行级锁

  • 幻读:一个事务内,多次读到了其他已提交事务的新增数据.对策:添加表级锁

  • 第一类丢失更新:A事务回滚时覆盖了事务B已提交的数据

  • 第二类丢失更新:A事务提交时覆盖了事务B已提交的数据

大部分数据库中使用提交读作为默认的隔离级别,这是出于性能和一致性的平衡,而MySQL中则默认采用可重复读作为配置。

4. 语法

4.1. 关闭/开启自动提交事务(只对当前会话有效)

set autocommit = off/on;   或者   set session autocommit = off/on;

4.2. 事务的使用

start transaction;BEGIN
DML语句...
COMMIT;   成功时提交,持久化数据,事务终结.
ROLLBACK;  失败时回滚,记录的操作都失效.事务终结

4.3. 修改隔离级别

SET [/session/global] transaction isolation level <isolation-level>

4.4. 查看隔离级别

SELECT @@[/session/global].tx_isolation   --会话/全局

results matching ""

    No results matching ""