面试100题:第61/63题数据库事务的四大特性以及隔离级别| ACID | MVCC

一、什么是事务?(transaction control language)

它是对数据进行访问与更新操作所组成的一个逻辑工作单元,要么成功完全执行,要么失败都不执行。

二、事务的四大特性(ACID原则)是什么?

1.原子性:事务在一次执行过程中只允许要么全部成功执行要么全部失败执行。
2.隔离性:一个事务的执行不能受到其他事务的影响。
3.持久性:一旦提交(commit),则持久化到数据库不能回滚(rollback)。
4.一致性:(事务完成提交)事务不能破坏数据库的完整性和一致性,一个事务执行前和执行后为从一个一致性状态转为新的一个一致性状态。若数据库一个事务在执行的过程中只成功部分执行则为不一致
难点:1.2.3.都是为了达到事务的一致性状态所以将一致性放到最后。

三、并发、异步下事务有可能发生的三大事务问题

在这里插入图片描述
Oracle,sql server默认隔离级别:读已提交,mysql:可重复读。
1.脏读:插入数据时候未提交就被查了但是结果是不对的。

问题定义:事务A向表中插入了一条数据,此时事务A还没有提交,此时查询语句能把这条数据查询出来,这种现现象称为脏读;
不能读取更新后的数

2.可重复读:别人已经在看这个表的数据结果这个表就被别人更新了数据,你再查一次结果就不一样了。

问题定义:一个事务A第一次读取的结果之后, 另外一个事务B更新了A事务读取的数据,A事务在第二次读取的结果和第一次读取的结果不一样这种现象称为不可重复读
多次读取的数不一致

3.幻读(串行化解决):别人已经在看这个表的数据结果别人就对这个表插入了一条数,查询结果就不一样了。

问题定义:事务A查询表里面的所有数据,这时事务B向表中插入了一条数据,这时事务A第一次的查询结果和第二次的查询结果不一致,这种现象我称为幻读。
不能读取插入后的数

四、事务的4个隔离级别

在这里插入图片描述
在这里插入图片描述

定义:解决三大事务问题,同时事务隔离级别越高,在并发下会产生的问题就越少,但同时付出的性能消耗也将越大,因此很多时候必须在并发性和性能之间做一个权衡。

4.1.1未授权读取=读未提交:
级别定义:读未提交,即能够读取到没有被提交的数据。
导致问题:所以很明显这个级别的隔离机制无法解决脏读、不可重复读、幻读中的任何一种,因此很少使用。

4.1.2授权读取=读已提交:
级别定义:即能够读到那些已经提交的数据,自然能够防止脏读。
导致问题:但是无法限制可重复读和幻读.

4.1.3不可重复读取:
级别定义:即在数据读出来之后加锁,类似"select * from XXX for update",明确数据读取出来就是为了更新用的,所以要加一把锁,防止别人修改它。REPEATABLE_READ的意思也类似,读取了一条数据,这个事务不结束,别的事务就不可以改这条记录,这样就解决了脏读、不可重复读的问题。
导致问题:幻读的问题还是无法解决。

4.1.4串行化:
级别定义:所有事物串行执行我理解为排队执行,事务只能一个一个执行不能并发执行。
导致问题:无

主要从该博客内容理解:链接: link.
相关知识多种锁的机制:链接: link.

ACID靠什么保证的?

原子性由undolog日志来保证,它记录了需要回滚的日志信息,事务回滚时撤销已经执行成功的sql

一致性是由其他三大特性保证,程序代码要保证业务上的一致性

隔离性是由MVCC来保证

持久性由redolog来保证,mysql修改数据的时候会在redolog中记录一份日志数据,就算数据没有保存成功,只要日志保存成功了,数据仍然不会丢失
在这里插入图片描述

传播机制

答:定义是多个事务方法相互调用,事务在方法间进行传播。有七种传播机制,默认传播机制是PROPAGATION_REQUIRED,用于@Trancation。

1、PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,
就加入该事务,该设置是最常用的设置。
2、PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当
前不存在事务,就以非事务执行。
3、PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果
当前不存在事务,就抛出异常。
4、PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
5、PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当
前事务挂起。
6、PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
7、PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,
则执行与 PROPAGATION_REQUIRED 类似的操作。

mysql事务隔离级别最最重要的概念MVCC

概念

​1.MVCC,Multi-Version Concurrency Control,多版本并发控制。MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问;在编程语言中实现事务内存。
2.如果有人从数据库中读数据的同时,有另外的人写入数据,有可能读数据的人会看到『半写』或者不一致的数据。有很多种方法来解决这个问题,叫做并发控制方法。最简单的方法,通过加锁,让所有的读者等待写者工作完成,但是这样效率会很差。MVCC 使用了一种不同的手段,每个连接到数据库的读者,在某个瞬间看到的是数据库的一个快照,写者写操作造成的变化在写操作完成之前(或者数据库事务提交之前)对于其他的读者来说是不可见的。
3.当一个 MVCC 数据库需要更一个一条数据记录的时候,它不会直接用新数据覆盖旧数据,而是将旧数据标记为过时(obsolete)并在别处增加新版本的数据。这样就会有存储多个版本的数据,但是只有一个是最新的。这种方式允许读者读取在他读之前已经存在的数据,即使这些在读的过程中半路被别人修改、删除了,也对先前正在读的用户没有影响。这种多版本的方式避免了填充删除操作在内存和磁盘存储结构造成的空洞的开销,但是需要系统周期性整理(sweep through)以真实删除老的、过时的数据。对于面向文档的数据库(Document-oriented database,也即半结构化数据库)来说,这种方式允许系统将整个文档写到磁盘的一块连续区域上,当需要更新的时候,直接重写一个版本,而不是对文档的某些比特位、分片切除,或者维护一个链式的、非连续的数据库结构。
4.MVCC 提供了时点(point in time)一致性视图。MVCC 并发控制下的读事务一般使用时间戳或者事务 ID去标记当前读的数据库的状态(版本),读取这个版本的数据。读、写事务相互隔离,不需要加锁。读写并存的时候,写操作会根据目前数据库的状态,创建一个新版本,并发的读则依旧访问旧版本的数据。
5.一句话讲,MVCC就是用 同一份数据临时保留多版本的方式 的方式,实现并发控制。
这里留意到 MVCC 关键的两个点:
在读写并发的过程中如何实现多版本;
在读写并发之后,如何实现旧版本的删除(毕竟很多时候只需要一份最新版的数据就够了)

6.MVCC在MySQL InnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读。
7.MVCC只在READ COMMITED 和 REPEATABLE READ两个隔离级别工作,其他不兼容因为READ UNCOMMITTED总是获取最新数据不符合版本控制、SERIALIZABLE则对所有读取的行进行加锁。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实现

MVCC 使用时间戳(TS)、递增的事务 ID(T)实现事务一致性。
MVCC 通过维护多版本数据,保证一个读事务永远不会被阻塞。对象 P 维护有多个版本,每个版本会有一个读时间戳(Read TimeStamp, RTS)和 写时间戳(Write TimeStamp, WTS),事务 Ti 读对象 P 的最新版本,该版本早于事务 Ti 的读时间戳 RTS(Ti)。
事务 Ti 要对 P 执行写操作,如果有其他事务 Tk 同时对 P 操作,则 RTS(Ti)必须要早于 RTS(Tk),即有 RTS(Ti) < RTS(Tk),这样对 Ti 对 P 的写操作才能完成。一般地,如果其他事务拥有 P 的一个更早的读时间戳的情况下,写操作是不能完成的。打个比方就是在存储前面有一道线,只有等你前面的人的完成了他们的事务,你的修改事务才可以提交完成。
重复说一下:每个对象 P 有一个时间戳 TS,如果事务 Ti 想要对 P 执行写操作,(写要先读)事务的读时间戳是 RTS(Ti),如果有其他事务拥有一个比较早的时间戳,有 TS§ < RTS(Ti),这时事务 Ti 会退出并重新开始。否则,事务 Ti 创建一个 P 的新版本,并设置新版本 P 的时间戳,似的 TS = TS(Ti)。
MVCC 系统明显的缺点是会存储多个版本数据的冗余开销。但同时,读操作永不会被阻塞,这对那些以读操作为主的数据库来说非常重要。MVCC 实现了真的快照隔离(snapshot isolation),然后其他的并发控制方法要么是不完整的快照隔离方式,要么需要较高的性能损耗。
Wikipedia 中的内容有点繁琐,简单地,上面的描述,阐明了在同一数据版本下写操作的限制,已经通过多版本实现快照隔离的优越性。

什么是MVCC?

1、MVCC

MVCC,全称Multi-Version Concurrency Control,即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。
MVCC在MySQL InnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读。

2、当前读

像select lock in share mode(共享锁), select for update ; update, insert ,delete(排他锁)这些操作都是一种当前读,为什么叫当前读?就是它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。

3、快照读(提高数据库的并发查询能力)

像不加锁的select操作就是快照读,即不加锁的非阻塞读;快照读的前提是隔离级别不是串行级别,串行级别下的快照读会退化成当前读;之所以出现快照读的情况,是基于提高并发性能的考虑,快照读的实现是基于多版本并发控制,即MVCC,可以认为MVCC是行锁的一个变种,但它在很多情况下,避免了加锁操作,降低了开销;既然是基于多版本,即快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本

4、当前读、快照读、MVCC关系

MVCC多版本并发控制指的是维持一个数据的多个版本,使得读写操作没有冲突,快照读是MySQL为实现MVCC的一个非阻塞读功能。MVCC模块在MySQL中的具体实现是由三个隐式字段,undo日志、read view三个组件来实现的。

MVCC解决的问题是什么?

  数据库并发场景有三种,分别为:

​ 1、读读:不存在任何问题,也不需要并发控制
​ 2、读写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读、幻读、不可重复读
​ 3、写写:有线程安全问题,可能存在更新丢失问题
​ MVCC是一种用来解决读写冲突的无锁并发控制,也就是为事务分配单项增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照,所以MVCC可以为数据库解决一下问题:
​ 1、在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能
​ 2、解决脏读、幻读、不可重复读等事务隔离问题,但是不能解决更新丢失问题

1.当一个事务在读取某一条记录,另一个事务在修改该事务,可能会导致读取该记录的事务读取到的记录不一致。有许多方法解决该问题,即统称为并发控制方法。
2.解决方案1:加锁,使读取的事务等待修改记录的事务完成后才能继续工作
3.更高效解决:MVCC数据库新增一条记录时就会将旧数据标记为过时切不会覆盖旧记录,实现多版本存储记录且有且只有一条记录是最新的。
4.MVCC提供了时间点一致性视图,MVCC在并发情况下读事务一般使用时间戳或者事务id标记数据版本。读写操作相互隔离不需要加锁。读写并存的时候,写操作会根据目前数据库的状态,创建一个新版本,并发的读则依旧访问旧版本的数据。

MVCC实现原理是什么?

总结:在读已提交隔离级别下,是每个快照读都会生成并获取最新的Read View,而在可重复读隔离级别下,则是同一个事务中的第一个快照读才会创建Read View,之后的快照读获取的都是同一个Read View.

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值