我正在参加「掘金·启航计划」
我们都知道,MySQL可以实现“事务”,那么什么是“事务”呢?我个人理解“事务”就是一系列操作的集合。
MySQL中的事务满足“ACID”特性。其中,“A” 是Atomicity原子性,这表示事务是数据库中的一个逻辑工作单位,也就是说一个事务中的操作,要么不做,要么全做,不存在一种中间态;“C” 是Consistency一致性,这也意味着事务执行的结果必须可以让数据库从一个一致性状态转移到另一个一致性状态,如果数据库中仅包含事务执行成功的结果,那么此时可以认为数据库就是处于一种一致性状态,反之,如果数据库在事务执行过程中宕机,而事务执行到一半的结果已经写入到物理数据库中,那么认为数据库此时就是处于一种不一致状态;“I” 是Isolation隔离性,也就是多个事务(无论并发与否)它们之间的操作是互相不可见、不能互相干扰的;“D” 是Durability持续性,指的是当一个事务提交后,它对数据库中数据的改变就应当是永久的,后续其他行为的操作不应对这个结果产生影响。
SQL标准中定义了4类隔离级别,每个级别中事务内外改变的可见性是不同的。隔离级别越低,代表着它可支持的并发度越高、系统开销越低。
在MySQL中,有两种方式可以查看当前会话的隔离级别:
SHOW VARIABLES LIKE 'transaction_isolation';
SELECT @@transaction_isolation;
这也是两种常见的查看MySQL系统变量的方法。
创建一张test表。
CREATE TABLE `t1` (
`uid` int(11) DEFAULT NULL,
`uname` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
并且向里面插入数据。
INSERT INTO t1 VALUES (1,'zhangsan'), (2,'lisi'),(3,'wangwu');
READ UNCOMMITTED(读未提交)
A事务
B事务
可以看到有A事务中出现了dirty read,也就是读到了B事务中没有提交的更改。
READ COMMITTED(读已提交)
A事务
B事务
可以很明显地看到A事务中dirty read的问题已经解决了,但是仍然会看到B事务已经提交的修改,这就是“不可重复读”问题。
REPEATABLE-READ(可重复读)
A事务
B事务
可以看到,dirty read和“不可重复读”的问题都解决了,但是出现了“幻读”的问题。
SERIALIZABLE(可串行化)
A事务
B事务
可以看到,由于B事务的修改涉及到A中的相应数据行,所以直接进行等待,这里有可能存在超时。