数据库笔记

1、数据库事务

1、什么是事务

​ |事务是数据库区别于其他文件系统的重要特性之一,事务会把数据库从一种一致性状态转换为另一种一致性状态

2、事务的特性

  • 原子性(Atomicity):整个事务要么全部提交成功,要么全部回滚,不会出现部分执行的情况(区分与redis,redis是要么全部执行,要么全部不执行,不会回滚事务)。
  • 一致性(Consistency):几个并行执行的事务,其执行结果必须与按某一顺序串执行的结果相一致。
  • 隔离性(Isolation):事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的。
  • 持久性(Durability):一个事务一但被提交了,那么对数据库中的数据改变就是永久的,及时数据库系统出现故障额情况下也不会丢失提交事务的操作

3、事务的隔离级别

1、写未提交(READ UNCOMMITTED):容易引发脏读、不可重复读、幻读;隔离级别最低

  • 事务2查询到了事务1中写未提交的数据,但因为事务1又进行了回滚数据,导致事务2查询的数据不正确,因此出现了脏读的情况。

2、写已提交(READ COMMITTED):会引发不可重复读、幻读

  • 事务2执行update语句但未提交前,事务1的前两个select操作返回结果是相同的,但事务2执行commit操作后,事务1的第三个select操作就读取到了事务2对数据的改变。导致与前两次select操作返回不同的数据,因此出现了不可重复读的问题。

3、可重复读(REPEATABLE READ):会引发幻读(MySQL默认隔离级别)

  • 事务没开启一个实例,都会给他分配一个版本号,如果读取的数据行郑在被其他事务执行DELETE或UPDATE操作(即该行上有排他锁),这是改事务的读取操作不会等待行上的锁释放,而是根据版本号去读取行的快照数据(记录在undo log中),这样事务中的查询操作返回的都是同一版本下的数据,解决了不可重复读的问题

  • 虽然解决了不可重复读的问题,但也导致了出现幻读的情况,一个事务在执行过程中,另一个事物对已有数据行的更改,MVCC机制虽然可以保障事务读取到的与原有数据行的内容相同,但并不能组织另一个事物插入新的数据行,这就当值该事物中凭空多出数据行,想出现了幻觉一样,这边是幻读。

4、可串行化(SERIALIZABLE):隔离级别最高,可解决前面的问题

  • 通过强制事务排序,使之不能相互冲突,这是在每个读得数据行加上共享锁来实现,但会造成大量的超时和锁竞争现象(读写数据都会加锁)
MySQL隔离级别 脏读 不可重复读 幻读
读已提交(read-uncommitted)
读未提交(read-committed) ×
可重复读(repeatable-read) × ×
串行化(serializable) × × ×

2、MVCC 多版本并发控制

1、什么是MVCC

MVCC(Multi Version Concurrency Control的简称),代表多版本并发控制。与MVCC相对的,是基于锁的并发控制(Lock-Based Concurrency Control)

2、MVCC是为了解决什么问题

  • 大多数的MySQL事务性数据引擎,如InnoDB,Falcon以及PBXT都不实用一种简单的锁机制,事实上,他们都和MVCC多版本并发控制来一起使用。
  • 锁机制可以控制并发操作,但是其系统开销较大,而MVCC可以在大多数情况下代替行级锁,降低其系统开销

3、MVCC具体实现

  • MVCC是通过在每行记录的保存两个隐藏的列来实现的,这两个列,一个保存了行的创建时间,一个保存行的过期时间。当然存储的并不是实际的时间值,而是系统版本号(system version number)。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。
    • InnoDB只查找版本早于当前事务版本的数据行(也就是,行的系统版本号小于或等于事务的系统版本号),这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的。
    • 行的删除版本要么未定义,要么大于当前事务版本号。这可以确保事务读取到的行,在事务开始之前未被删除。