事务隔离级别
- 读未提交(read uncommitted),事务未提交,它做的变更就可被其他事务看见
- 读已提交(read committed),事务提交后,它做的变更才可见
- 可重复读(repeatable read),事务在执行过程中看到的数据,与事务开启时看到的数据是一致的
- 串行化(serializable),顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。
事务隔离级别的实现机理
事务上的视图
事实上,当一个事务访问一条记录时,数据库服务器会为这个这条记录生成一个视图,而事务访问时都会以这个视图的逻辑结果为准;
- 读未提交没有视图的概念,它总是读取一条记录的最新值
- 读已提交,视图是在每个SQL执行的时候生成的,因此如果是同一条SQL,每次执行的视图可能会不一样(也就是如果当前记录被已提交事务修改)
- 可重复读,视图是在事务开启的时候生成的,因而事务的整个存在期间(未提交前)都是以这个视图为准的
- 串行化,直接用加锁的方式避免事务的并行访问
如何查看当前事务的隔离级别
1
show variables like 'transaction_isolation';
事务的多版本并发控制
从日志系统那一章我们知道:在 InnoDB 中每次进行更新操作时都会在 redo log 中进行记录,而事务中的最新值可以通过 redo log 回滚到前几个状态的值。事实上事务的原子性就是通过 redo log 实现。
假设在当前的事务中,一条数据经过了如下变化:
其中 read-view 代表视图,而对于不同时刻启动的事务,会分别用不同的视图,使得同一条数据在不同的事务居然会有呈现不同的值,比如上图一共有 A、B、C 三个视图,数据的值分别是 1、2、4。这就是数据库的多版本并发控制(MVCC)。
事务的启动方式
手动操作事务:
1
2
3
4
5
6
7
8
9
10
11
12
-- 关闭事务的自动提交
set autocommit=0
-- 开启事务(或者 start transaction)
begin
-- 提交事务
commit
-- 回滚事务
rollback
-- 提交事务并自动开启下一个事务
commit work and chain
-- 查找持续时间超过60s的事务
select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60;