MySQL事务面试题

MySQL事务面试题

事务有哪几种隔离级别呢?可以详细谈谈吗?

MySQL中InnoDB存储引擎实现了SQL标准的4种隔离级别,主要用来限定事务内哪些改动是可见的,哪些是不可见的。低级别的隔离一般支持更高的并发处理,并拥有更低的系统开销。

MySQL中可以通过show variables like '%tx_isolation%'查看当前事务的隔离级别。默认使用的是REPEATABLE-READ。记忆技巧:isolate 孤立 e改 tion 表名词。读音:[aslen]

读未提交(read uncommitted)RU:一个事务可以读到其它事务未提交的数据,这种现象叫做脏读,在生产环境不建议使用。

数据库的读以提交(read committed)RC:一个事务可以读到其它事务已提交的数据。也可以叫做不可重复读,允许幻读现象的发生,是oracle数据库默认的事务隔离级别。

可重复读(repeatable read)RR:它是MySQL默认的事务级别,一个事务开始到结束,都可以反复读取到事务开始时看到的数据,并一直不会发生变化,避免了脏读、不可重复读和幻读现象的发生。

串行(serializable):读写都会锁住整张表,保证数据不会出错,在读数据的时候会加表级共享锁,在每次写数据的时候都会加表级排他锁。这个级别会导致InnoDB并发大幅下降,会发生大量超时和锁竞争,开发中很少用。

详细说说脏读、不可重复读、幻读、可重复读以及幻读与不可重复读的区别

脏读:RU事务隔离级别中,一个事务可以读取到其他事务还没有提交数据的现象。

不可重复读与幻读:一个事务读取到其它事务对旧数据做的修改记录,比如delete、update。

可重复读:这是MySQL默认事务隔离级别,它可以更好地保证数据一致性。比如会话A在RR级别的事务中新增了一条数据。会话B读取到的还是一开始的数据,并没有读取到新增的那条,如果想要读取到会话A新增的那条需要在语句后面加for update,或者执行commit。这个级别一般用于对事务要求较高的网站,比如某宝网。

不可重复读的重点是修改:在同一事务中,同样的条件,第一次读的数据和第二次读的数据不一样。(因为中间有其他事务提交了修改)。

幻读的重点在于新增或者删除:在同一事务中,同样的条件,第一次和第二次读出来的记录数不一样。(因为中间有其他事务提交了插入/删除)。

事务并发一般都会产生哪些问题?

更新丢失(Lost Update):当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题,最后的更新覆盖了由其他事务所做的更新。

脏读(Dirty Reads):一个事务正在对一条记录做修改,在这个事务没有提交前, 这条记录的数据就一直处于不确定状态; 这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些脏数据,并据此做进一步的处理,就会产生未提交的数据依赖关系,这种现象被形象地叫做脏读。

不可重复读(Non-Repeatable Reads):一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种现象就叫做“不可重复读” 。

幻读(Phantom Reads): 一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读” 。

应该如何解决?

并发事务可能造成:脏读、不可重复读和幻读等问题 ,这些问题其实都是数据库读一致性问题,必须由数据库提供一定的事务隔离机制来解决,解决方案如下:

加锁:在读取数据前,对其加锁,阻止其他事务对数据进行修改。例如,读的时候加共享锁,此时其他事物无法修改相应的数据,写的时候加排他锁,禁止其他事物读写操作,但是这种做法性能较差。

基于性能考虑MySQL提供了数据多版本并发控制(MVCC),也称为多版本数据库:不用加任何锁, 通过一定机制生成一个数据请求时间点的一致性数据快照(Snapshot), 并用这个快照来提供一定级别 (语句级或事务级) 的一致性读取,从用户的角度来看,好象是数据库可以提供同一数据的多个版本。

什么是MVCC?

MVCC 全称是多版本并发控制系统,InnoDB 和 Falcon 存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决幻读问题。

MVCC工作原理是啥?

InnoDB 的 MVCC 是通过在每行记录后面保存两个隐藏的列来实现,这两个列一个保存了行的创建时间,一个保存行的过期时间(删除时间)。当然存储的并不是真实的时间而是系统版本号(system version number)。

每开始一个新的事务,系统版本号都会自动新增,事务开始时刻的系统版本号会作为事务的版本号,用来查询到每行记录的版本号进行比较。

REPEATABLE READ(可重读)隔离级别下 MVCC 如何工作?

SELECT:InnoDB 会根据以下条件检查每一行记录:第一,InnoDB 只查找版本早于当前事务版本的数据行,这样可以确保事务读取的行要么是在开始事务之前已经存在要么是事务自身插入或者修改过的。第二,行的删除版本号要么未定义,要么大于当前事务版本号,这样可以确保事务读取到的行在事务开始之前未被删除。
INSERT:InnoDB 为新插入的每一行保存当前系统版本号作为行版本号。
DELETE:InnoDB 为删除的每一行保存当前系统版本号作为行删除标识。
UPDATE:InnoDB 为插入的一行新纪录保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为删除标识保存这两个版本号,使大多数操作都不用加锁。它不足之处是每行记录都需要额外的存储空间,需要做更多的行检查工作和一些额外的维护工作。
MySQL 可重复读隔离级别并没有彻底解决幻读,只是很大程度上避免了幻读现象的发生。
https://blog.csdn.net/qq_52297656/article/details/127930062

MySQL 事务实现原理是什么?

事务的实现是基于数据库的存储引擎,不同的存储引擎对事务的支持程度不一样。MySQL 中支持事务的存储引擎有InnoDB 和 NDB。
InnoDB 是高版本 MySQL 的默认的存储引擎,因此就以 InnoDB 的事务实现为例,InnoDB 是通过多版本并发控制(MVCC,Multiversion Concurrency Control )解决不可重复读问题,加上间隙锁(也就是并发控制)解决幻读问题。
因此 InnoDB 的 RR 隔离级别其实实现了串行化级别的效果,而且保留了比较好的并发性能。事务的隔离性是通过锁实现,而事务的原子性、一致性和持久性则是通过事务日志实现。
如何设置 MySQL 的事务隔离级别?

MySQL 事务隔离级别 MySQL.cnf 文件里设置的(默认目录 /etc/my.cnf),在文件的文末添加配置:transaction-isolation = REPEATABLE-READ
READ-UNCOMMITTED/READ-COMMITTED/REPEATABLE-READ/SERIALIZABLE
或:set global | session tx_isolation=‘READ-COMMITTED’;命令修改隔离级别。
MySQL> set global transaction isolation level read committed; // 设置全局事务隔离级别为 read committedMySQL> set session transaction isolation level read committed; // 设置当前会话事务隔离级别为 read committed

InnoDB 如何开启手动提交事务?

InnoDB 默认是自动提交事务的,每一次 SQL 操作(非 select 操作)都会自动提交一个事务,如果要手动开启事务需要设置
set autocommit=0
禁止自动提交事务,相当于开启手动提交事务。

在 InnoDB 中设置了 autocommit=0,添加一条信息之后没有手动执行提交操作,请问这条信息可以被查到吗?

autocommit=0 表示禁止自动事务提交,在添加操作之后没有进行手动提交,默认情况下其他连接客户端是查询不到此条新增数据的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值