一. 事务的四个基本特性(ACID)
1. 原子性(Atomicity)
- 同一个事务所包含的所有操作,要么全做,要么全不做,任何一项操作的失败都会导致整个事务的失败;
2. 一致性(Consistency)
- 当事务结束后,系统在执行事务操作前后的状态是一致的;
- 这里举个例子来说,比如A(余额300元)转账给B(余额200元),在一个事务中,无论A转了多少钱,转了几次,在事务完成后,A和B的总金额还是500元;
3. 隔离性(Durability)
- 并发执行的多个事务操作是相互隔离,互不影响的,并且无法看到其他事务的中间状态;
- 数据库提供了多种隔离级别,这块后面会说道。
4. 持久性
- 事务完成后所做的所有改动都会被持久化,永久生效,即使数据库发生了灾难性故障也不会对已经完成的事务结果造成影响。
二. 事务隔离级别
在高并发情况下,要完成保证事务ACID特性是十分困难的,除非把所有的事务串行化执行,但是因此造成的影响将是系统性能大大降低。在实际开发中很多业务对事务的要求是不一样的,因此数据库设计了四种隔离级别供用户基于业务进行选择。
隔离级别 | 脏读(Dirty Read) | 不可重复读(Non-repeatable Read) | 幻读(Phantom Read) |
---|---|---|---|
读未提交(Read uncommitted) | 可能 | 可能 | 可能 |
读已提交(Read committed) | 不可能 | 可能 | 可能 |
可重复读(Repeatable read) | 不可能 | 不可能 | 可能 |
串行化(Serializable) | 不可能 | 不可能 | 不可能 |
- 脏读:
一个事务读取到另一个事务还未提交的数据。 - 不可重复读:
在同一个事务中,前后两次执行相同的查询操作,出现返回的结果不一致的情况,换言之就是后一次查询操作能够读取到其他事务已提交的更新数据;“可重复读” 与之相反,是指在同一个事务中,前后两次查询操作读取到的结果一致,其他事务提交的更新数据不会对本事务造成影响。 - 幻读:
查询表中一条记录,如果发现不存在就插入一条,并发情况下,发现表中出现两条相同记录,这就是幻读。
三. 数据库默认的隔离级别
- Oracle默认隔离级别是Read committed;
- MySQL默认是Repeatable read,另外在MySQL中执行一条查询语句默认是一个独立事务操作,所以看上去效果跟Read committed一样;
- 查看MySQL隔离级别信息:
select @@tx_isolation;
- 设置MySQL隔离级别:
set [global|session] transaction isolation level 隔离级别名称;
或
set tx_isolation=’隔离级别名称;’
可选参数:
- READ-UNCOMMITTED
- READ-COMMITTED
- REPEATABLE-READ
- SERIALIZABLE