一、事务的基本要素(ACID)
- 原子性(Atomicity):即不可分割性,事务要么全部被执行,要么全部不执行
- 一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏。比如A向B转账,不可能A扣了钱,B没有收到。
- 隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束钱,B不能向这张卡转账。
- 持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚
二、事务的并发问题
1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
3、幻读:幻读解决了不重复读,保证了同一个事务里,查询的结果都是事务开始的状态(一致性)。
三、mysql事务隔离级别
- READ_UNCOMMITTED (未授权读取):最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读,幻读,不可重复度 (俗称:RU)
- READ_COMMITTED(授权读取):允许读取并发事务已经提交的数据,可以阻止脏读,可能会导致幻读,不可重复读 (俗称:RC)
- REPEATABLE_READ(可重复读):对同一字段的多次读取结果都是一致的,除非数据是被本事务自己所修改,可以阻止脏读,不可重复度,可能会导致幻读
- SEARIALIZABLE(序列化):最高的隔离级别,完全服从ACID隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读,幻读,不可重复读。但是这样严重影响程序的性能。通常情况下也不会用到该级别
事务隔离级别 | 脏读 | 幻读 | 不可重复读 |
---|---|---|---|
READ_UNCOMMITTED(RU) | √ | √ | √ |
READ_COMMITTED(RC) | √ | √ | |
REPEATABLE_READ(RR) | √ | ||
SEARIALIZABLE(S) |
注意:
mysql默认采用的是REPEATABLE_READ(可重复度)隔离级别;
Oracle默认采用READ_COMMITTED(授权读取)隔离级别)
四、事务隔离级别实现原理
事务隔离级别 | 原理 |
---|---|
未授权读取(RU) | A事务对当前被读取的数据不加锁;B事务修改数据,必须先对其加行级共享锁,事务结束才释放 |
授权读取(RC) | A事务读取数据加了行级共享锁,读取数据结束立即释放;B事务修改数据必须先对其加行级排它锁,事务结束才释放 |
可重复读(RR) | A事务读取数据加行级共享锁,直到事务结束才释放;B事务修改数据必须先对其加行级排它锁,直到事务结束才释放 |
序列化读(S) | A事务读取数据加表级共享锁,直到事务结束才释放;B事务更新数据必须先对其加表级排它锁,直到事务结束才释放 |