一、事务(数据库的事务都通用的定义)
1.1 事务定义
事务是由一步或几步数据库操作序列组成逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行。事务通常以 BEGIN TRANSACTION
开始,以COMMIT
或 ROLLBACK
操作结束:
COMMIT
即提交,提交事务中所有的操作、事务正常结束;ROLLBACK
即回滚,撤销已做的所有操作,回滚到事务开始的状态。
1.2 事务的四种特性
ACID: 原子性,一致性,隔离性,持久性。
ACID属性 | 含义 |
---|---|
原子性(Atomicity) | 指事物在逻辑上是不可分割的操作单元,所有语句要么都执行,要么都撤销执行。 |
一致性(Consistent) | 一个事务本质是将数据从一种一致性状态转换到另一种一致性状态,具体取决于现实生活的逻辑。(比如转账,A转给B,操作前后A+B的钱是不变的) |
隔离性(Isolation) | 隔离性是针对并发事务而言的,同时处理多个事务的时候,数据库的事务提供了不同的隔离级别来保证正确。 |
持久性(Durable) | 事务一旦提交,对于数据的修改是持久性的,数据更新的结果已经从内存转存到外部存储器,即使系统故障,已提交的数据更新也不会丢失。 |
这四个特性在没有并发的时候显然很容易满足,但是在并发处理事务的情况下,可能会带来一些问题
问题 | 含义 |
---|---|
丢失更新(Lost Update) | 当两个或多个事务操作同一行,后面的事务修改的值会覆盖前面的事务修改的值。 |
脏读(Dirty Reads) | 一个事务读到了被另一个事务修改,但尚未提交的事务。当一个事务正在多次修改一个数据,而这一系列修改还没有最后提交,另一个并发事务来读取了,就会导致错误。也就是另一个事务读到了脏数据。 |
不可重复读(Non-Repeatable Reads) | 一个事务操作的过程里,先读取一个数据,后来又读取,而两次读出的数据值不一致。就是因为中间被别的事务修改了。 |
幻读(Phantom Reads) | 一个事务按照相同的查询条件查两次,第一次查出了A集合,第二次却不是了,因为其他事务插入了数据,正好满足这个事务的查询条件。 |
注意事项:
脏读
和不可重复读
的区别:脏读读到的脏数据是另一个事务没有提交的数据,但是不可重复读读到错误数据是因为另一个事务把数据修改并提交了;幻读
和不可重复读
的区别:幻读和不可重复读都是读到了另一个事务提交的数据,但是不可重复读是两个事务针对同一个数据项,而幻读针对的是一个数据整体(数据条目)
为了解决上述提到的事务并发问题,数据库提供一定的事务隔离机制来解决这个问题。
数据库的事务隔离越严格,并发副作用越小,但付出的代价也就越大,因为事务隔离实质上就是使用事务在一定程度上“串行化” 进行,这显然与“并发” 是矛盾的。
隔离级别 | 中文事务 | 解决问题 |
---|---|---|
RU:READ UNCOMMITED | 未提交读(很少使用,基本没有解决问题) | 丢失更新 |
RC:READ COMMITED | 提交读。顾名思义,保证一个事务只能看见另一个事务已经提交的事务的结果。 | 丢失更新+脏读 |
RR:REPEATEABLE READ(Innodb默认) | 可重复读。顾名思义,解决了第三个并发问题:不可重复读。 | 丢失更新+脏读+不可重复读 |
S:SERIALIZABLE | 序列化。通过强制事务排序来让他们串行执行。(也很少使用)本质上是给每个数据行都加上了共享锁 | 四个问题都解决了 |
从上往下,隔离级别越来越高,但是代价肯定越来越大,真正选择的时候需要斟酌,可以看到,要想真正解决幻读问题&#x