事务的特性
ACID
- A(
Atomicity
):原子性 - C(
Consistency
):一致性 - I(
Isolation
):隔离型 - D(
Durability
):持久性
隔离引发的问题
脏读、幻读、不可重复读、丢弃修改
-
脏读:A事务读取到B事务未提交的数据
脏读.png -
幻读/虚读:A事务读B事务提交的数据,在B事务提交前后读取到的数量不一致
幻读.png -
不可重复读:A事务读B事务提交的数据,在B事务提交前后读取到的数据不一致
不可重复读.png
-丢弃修改:A、B事务对一个数据进行修改,A先修改,B后修改,B修改覆盖了A修改的
丢弃修改.png事务隔离级别
读未提交、读提交、可重复读、串行化
- 读未提交:A事务没有提交,其他事务能读取到A的变更。导致脏读。
- 读提交:A事务没有提交,其他事务不能读A的变更,只有A提交事务后才能被读取。解决了脏读,会导致幻读/虚读、不可重复读。
oracle
默认的隔离级别 - 可重复读:一个事务执行过程中看到的数据总是一致的。可以解决脏读、不可重复读。
mysql
默认的隔离级别。 - 串行化:读会加读锁,写会加写锁,所有操作都是串行的。可以解决脏读、幻读/虚读、不可重复读。
LBCC
和MVCC
InnoDB
默认级别时可重复读(Repeatable Read
),为了解决该隔离级别下的幻读问题,提出了LBCC
和MVCC
LBCC
为了解决当前读情况下的幻读。
MVCC
为了解决普通读(快照读)的幻读。
当前读:Locking Read
锁定读,读取当前数据的最新版本,并对这个数据加锁,防止别的事务更改来解决当前读的问题。在进行写操作的时候就需要进行当前读,读取数据记录的最新版本。
快照读:Read View
,在可重复读隔离级别下,我们可以把每次select
当作一次快照读
LBCC
:Lock-Based Concurrent Control
基于锁的并发控制
MVCC
:Multi-Version Concurrent Control
基于多版本的并发控制
问答
mysql
隔离级别为什么默认可重复读?
因为Mysql
的binlog
日志的格式在5.0之前,只有statement
模式,记录的是修改sql语句,如果mysql
默认隔离级别为读提交,主从同步会出现数据不一致的bug
。
例:
A提交事务为删除id
>10的,B提交事务为insert
一条id
为11的数据,A在B提交后再提交。这时候master
执行的顺序是先删后插,statement
记录的是先插后删,slave
同步到的binlog
日志也是先插后删,这时候,主从同步不一致的bug
就出来了。
推荐:
如果用mysql
5.0+,隔离级别为读提交(Read commit
),使用的是InnoDB
引擎时,binlog
日志模式推荐使用row
模式
InnoDB
引擎binlog
日志有几种模式(Myisam
引擎不支持事务)?
5.0之前只有statement
,5.0之后有三种:
-
statement
:记录的是修改sql语句。 -
row
:记录的是每行实际数据的变更。 -
mixed
:statement和row模式的混合。
网友评论