1. 事务的ACID特性
事务的特性主要有四种,简称为ACID。分别如下:
- 原子性(atomicity):一个事务内是一个最小的操作单元,在此单元里操作成功或者失败都是同步的,不会存在部分成功部分失败的问题。
- 隔离性(isolation):多个事务之间是隔离开的,事务之间对数据的操作是不会互相影响的。但是对于数据库来说有不同的隔离级别,事务之间的影响也是不同的。
- 一致性(consistency):在一个事务中,操作的数据是最终一致的,用官方的话说就是数据库总是从一个一致性的状态转换到另一个一致性的状态。如A给B转钱,A账户扣钱,B账户也会有相等的金额入账。
- 持久性(durability):事务执行结束后,数据所做的修改都会被持久化到数据库中。
事务的原子性、一致性和持久性比较容易理解。但是隔离性是因具体的隔离级别的不同而不同的。按照官方的说法就是一个事务所做的修改在最终提交以前,对其他事务是不可见的。如上所说,这种说法准确性是受隔离级别的影响的。
2. 事务隔离级别
事务的隔离性是事务的四大特性之一,在隔离性上,又被分为四个不同的等级,分别表示对事务的控制程度。从数据的安全性的级别也是依次上升的。
2.1 事务数据存在问题
在说事务隔离级别前需要先看一下事务在各种隔离级别中可能存在的问题。
- 脏读:就是在一个事务中执行的操作还未提交,其他事务就会读到这些未提交的数据。脏读又可称为读未提交。
- 不可重复读:在A事务中执行了update、delete操作提交后,导致其他事务在A事务前后读取的数据不一致。
- 幻读:当A事务里面执行了insert操作,其他事务中在A事务前后读取的数据不一致。
脏读和其他两种很好区分,但是不可重复读和幻读需要稍微理解一下,注意上面的表述就可以知道,不可重复读是针对update、delete操作,而幻读是针对insert操作的。
再加上图来理解:
此图是幻读的流程图,读已提交和这张图类似,就是讲Joker的insert操作变为update、delete操作即可。至于脏读很好理解,这里就不多做描述啦。
2.2 事务的四种隔离级别
上面说了事务的数据存在的问题,下面就结合上面的问题说明一下事务的四种隔离级别。
- 未提交读(read uncommit):就是脏读,同时也有幻读和不可重复读的问题。
- 已提交读(read commit):这个隔离级别是Oracle数据库的默认隔离级别。解决了脏读问题,但是存在不可重复读和幻读的问题。
- 可重复读(repeatable read):此隔离界别是MySQL数据库的默认隔离级别。解决了上面的脏读和不可重复读问题,但是依然存在幻读的问题。
- 可串行化(serializable):此隔离界别是最严格的一个,当多个事务同时执行的时候,在数据库都是采用排队的机制,不允许两个事务在同一时间操作,觉得的解决了上面的脏读、不可重复读、幻读问题。但是同时带来了执行效率问题。
下面来列一个表格说明一下:
隔离级别 | 脏读 | 不可重复读 | 幻读 | 效率 |
---|---|---|---|---|
未提交读(read uncommited) | 是 | 是 | 是 | 4(最高) |
已提交读(read commited) | 否 | 是 | 是 | 3(次之) |
可重复读(repeatable read) | 否 | 否 | 是 | 2(次次之) |
可串行化(serialiable) | 否 | 否 | 否 | 1(最低) |