数据库事务同时访问数据时,可能会遇到一些问题,因此数据库将设置四个不同的隔离级别来解决问题。
MySQL数据库中的隔离级别分为四个级别:读取未提交、读取提交、可重复读取和序列化。 与此相对应,发生的问题有污读、幻读、不可重复的读。
隔离级别
读未读(read uncommited )
如果一个事务尚未提交,则该更改将显示在其他事务中。
读提交(read commited )
在提交一个事务之前,其他事务中不会看到该更改
可重复(repeatable read )。
在一个事务执行过程中看到的数据始终与该事务启动时看到的数据相匹配。 在此隔离级别上,其他事务也看不到未提交的事务。
序列化(serializable )
对于同一行的记录,“写”带有“写的密钥”,“读”带有“读的密钥”。 如果发生读/写锁定冲突,则在上一个事务执行完成之前,以后访问的事务不能继续执行。
此隔离级别可确保数据的准确性,但频繁的封锁对性能有很大影响。
对应于不同事务隔离级别的问题
潦草的读法
在“读取未提交的更改”级别,未提交的更改对其他事务可见,而未提交的更改对其他事务来说是脏数据,这被称为脏数据。
不要重复
在" readcommit "级别,只有在提交事务之前,其他事务才能看到事务中的更改。 但是,一个事务a在执行过程中多次查询值,在第一个查询中为v1,然后在事务b中更改值。 当事务a再次查询时,您会发现此值不同。 明明是同一事务执行的查询操作,但查询两次的结果不同。 这是“不能重复”
幻读
“幻像读取”类似于“不可重复读取”。 事务a查询某个值,如果不存在,则插入它。 查询事务a不存在后,事务b会插入此值,当事务a再次去插入时,您会发现查询中存在以前不存在的值。 要解决幻像读取问题,请将事务隔离级别设置为“序列化”。 也就是说,无论读/写都锁定数据。
要区分事务a的事务b启动事务a,请执行以下操作:
查询获取值1并启动事务b
查询获取值1
把1改为2
查询得到值v1
提交事务b
查询得到值v2
提交事务a
如果查询得到的值v3隔离级别为“未读”,则v1的值为2。 此时事务b尚未提交,但结果已在a中可见。 因此,v2、v3都是2。
如果隔离级别为“读取提交”,则v1为1,v2的值为2。 事务b的更新在提交后显示在a中。 因此,v3的值也是2。
如果隔离级别为“可重复”,则v1、v2为1,v3为2。 在“可重复读取”级别,必须遵循此要求。 事务执行过程中显示的数据前后必须始终相同。
如果隔离级别为“序列化”,则事务b在执行“将1更改为2”时被锁定。 事务b可以在知道事务a已提交后继续执行。 因此,从a的角度来看,v1、v2的值为1、v3的值为2。
事务隔离级别的实现在数据库中创建视图,并基于访问时视图的逻辑结果。 在“可重复读取”隔离级别下,此视图是在事务启动时创建的,并在事务执行期间使用。
在readcommit级别,此视图是在每个SQL语句开始执行时创建的。
如果处于“未读”级别,则直接返回记录的最新值。 没有视图的概念。 在序列化级别,直接使用锁定以避免并行访问。 公众号:无梦大意的热狗回复“群聊”,一起学习,一起进步
疑问加站长微信联系(本论文作者以外) ) ) ) ) )。