什么是事物
数据库事物:是指对于数据库的一系列操作指令的集合,通常这个集合是作为一个整体单元去执行,如果有其中一步出错,则整个操作都需要回滚,以保证数据的一致性和完整性
1. 事物的四个属性 (ACID)
- 原子性(A) : Atomicity 指一个事物是一个整体,是原子操作不可以在分割,一个事物要么全部成功要么全部失败
- 一致性© : Consistency 指事物执行的前后,数据库的完整性不能被破坏
- 隔离性(I) : Isolation 事物与事物之间存在隔离,防止修改冲突,互相不能干扰
- 持久性(D) : 事物完成后,对数据库的影响是永久的
2.事物的隔离级别
考虑到事物的隔离性,如果我们在并发时,既为了保证性能,也想保证数据的完整性,我们设置了不同的事物隔离级别
不同的隔离级别会产生不同的错误现象
- 脏读 : 是指读取了另一个事物未提交的数据,视为脏数据
- 不可重复读 : 在多次读取同一个数据的内容时,读取到的数据不一样,是指在读取过程中,别的事物对数据进行了修改 update
- 幻读 : 在读取相同查询条件下的数据时, 发现读取的条数不同,是指在查询过程中,别的事物进行了 新增或者 删除 insert or delete
针对不同的错误类型,我们设置不同的隔离级别来去除这些问题
- 读未提交 (read uncommitted) : 最低隔离级别,可以读取未提交的事物数据 : 三种情况都可能发生
- 读提交(read committed) : Oracle默认隔离级别,可以并发读取另一个事物提交的数据: 可防止脏读
- 可重复读 (repeatable read) : Mysql默认隔离级别, 对于同一个数据的读取是一致的 : 可防止脏读和不可重复读的发生
- 串行化 (serializable) : 可防止三类错误, 完全遵守ACID原则,在分布式事物中默认是串行化配置
需要注意的是:
- 事物的隔离机制是通过锁和并发调度实现的,并发调度通过MVCC实现,核心是保存旧版本的数据,进行比对和回滚
- 越高级别的事物意味着越多的锁,也就对性能有了影响,所以大多数数据库使用的都是 (read committed) 读提交级别,但是对于Mysql来说他的搜索引擎 InnoDB 他的默认级别就是(repeatable read) 可重复读,实践证明性能也不错
- InnoDB在实现分布式事物的时候,会将隔离级别提高至(serializable) 串行化
MVCC(多版本并发控制-Multi-Version Concurrency Control)的问题
MVCC 是乐观锁的一种实现方式 , 可以解决这样的问题:既然不想阻塞等待最新的数据,那就无视当前持有锁的事务,读取最新的历史版本数据。
这就解决了,在读数据时,有写数据占用锁时的等待,直接读取最新的快照
如果没有MVCC那么事物在并发写的时候,就只能等待互斥锁,这样会极大的消耗性能,有了MVCC我们可以通过创建历史数据的快照,实现 读写,写读,读读快速通行,大大的提高了效率
MVCC的实现:
- 实时保留数据的一个或者多个版本
- 根据情况在需要时通过undo日志创建临时版本
小结
各个隔离级别都中的实现原理小结
在读未提交时,会读取数据库最新的数据,产生脏读,不可重复读,幻读的问题
在读提交和可重复读级别中都会使用MVCC视图来进行控制读写控制,不同的是在读提交级别中,MVCC作用在每一个select语句上,所以会导致不可重复读的问题,而可重复读级别MVCC会在开局时生成视图,在整个事物中都使用开局视图,这样就防止了不可重复读的问题
在串行化级别中,使用直接加锁处理,这样虽然极大的提高了数据的可靠性,但是大大降低了并发性能