事务隔离
为什么要有事务隔离
数据库会并发执行多个事务,不同的事务可能会对同一批数据进行增删改查操作,就会引起数据脏写、脏读、不可重复读、幻读等情况。本质上都是由于事务之间的并发导致,简单点说就是事务之间互相影响,导致数据不一致问题。
事务隔离机制就是解决多事务并发的一种方式。
事务及其ACID属性
事务是由一组sql组成的逻辑处理单元。具有ACID四个属性:
- 原子性(Atomicity) 事务是一个原子操作单元,不可分割,要么全部执行,要么全部不执行。
- 一致性(Consistent)事务开始和完成时,数据必须保持一致状态。
- 隔离性(Isolation)事务之间是相互独立的,中间过程对外是不可见的。
- 持久性(Durable)事务完成之后,数据的修改是永久的,即使出现故障也能保持。
事务并发带来的问题
- 更新丢失 事务在更新时,都基于最初读取的值进行更新,不同事务之间不知道其他事务存储,后面的事务的更新覆盖了其他事务的更新。
- 脏读 第一个事务修改了数据,但是还未提交,第二个事务读取到这些修改后的数据,如果再基于这些数据进行修改提交,此时第一个事务如果回滚,第二个事务读取的数据应该是无效的,出现数据不一致。简单来说,事务B读取到了事务A修改但未提交的数据。
- 不可重复读 第一个事务读取数据以后,第二个事务修改数据并提交,第一个再次读取相同的数据,会发现和第一次读取的数据不一样。在同一个事务里面,相同的查询语句在不同时刻读的结果不一致。
- 幻读 第一个事务读取一批数据,第二个事务插入数据并提交,第一个事务再次读取,发现数据与之前读取的数据相比有新增数据。事务A读取到了事务B的新增数据,不符合隔离性。
事务隔离级别对上述问题的解决
隔离级别 | 脏读 (Dirty Read) | 不可重复读 (NonRepeatable Read) | 幻读 (Phantom Read) |
---|---|---|---|
读未提交 (Read Uncommitted) | 可能 | 可能 | 可能 |
读已提交 (Read Committed) | 不可能 | 可能 | 可能 |
可重复度 (Repeatable Read) | 不可能 | 不可能 | 可能 |
串行化 (Serializable) | 不可能 | 不可能 | 不可能 |
Mysql默认隔离级别是可重复读(RR)。
查看当前库隔离级别:show variables like ‘tx_isolation’;
设置隔离级别: set tx_isolation = ‘REPEATABLE-READ’;