并发事务问题与隔离级别
多个事务并发执行时会互相影响,出现脏读、不可重复读、幻读三类问题;数据库通过事务隔离级别来控制这些问题。
一、并发事务问题
| 问题 | 描述 |
|---|---|
| 脏读 | 一个事务读到另外一个事务还没有提交的数据 |
| 不可重复读 | 一个事务先后读取同一条记录,但两次读取的数据不同 |
| 幻读 | 一个事务按照条件查询数据时没有对应的数据行,但在插入数据时又发现这行数据已经存在,好像出现了「幻影」 |
三者的区别:脏读读到了别人未提交的数据;不可重复读是同一条记录两次读到的值不一样(别人改了并提交);幻读是结果集的行数变了(别人插入/删除了并提交)。
二、事务隔离级别
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| Read uncommitted | √ | √ | √ |
| Read committed | × | √ | √ |
| Repeatable Read(MySQL 默认) | × | × | √ |
| Serializable | × | × | × |
(√ 表示该级别下此问题仍可能发生,× 表示已解决)
-- 查看事务隔离级别
SELECT @@TRANSACTION_ISOLATION;
-- 设置事务隔离级别
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE};
注意:事务隔离级别越高,数据越安全,但是性能越低。
三、速查
| 事项 | 内容 |
|---|---|
| 三类并发问题 | 脏读 → 不可重复读 → 幻读(严重程度递减) |
| 默认隔离级别 | REPEATABLE READ(可重复读) |
| 最安全 / 性能最低 | SERIALIZABLE |
| 查看 | SELECT @@TRANSACTION_ISOLATION; |
| 设置 | SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL ...; |