数据库事务的特性、隔离级别以及丢失更新的处理

数据库事务的特性

数据库事务的特性包括原子性、一致性、隔离性、持久性。

  • 所谓原子性,就是指一个事务中的所有操作要么全成功,要么全失败;
  • 所谓一致性就是指事务执行前后都必须处于一致性的状态;
  • 所谓隔离性,是指开启的事务不能被其他的事务所影响,多个并发事务彼此隔离;
  • 所谓持久性表示事务正确执行完后对于数据的改变是永久的。

其中,关于隔离性,数据库的隔离级别有四种,分别是读未提交,读已提交,可重复读、串行化。
梳理四种隔离级别前,先来了解下事务并发时有3种常见的问题——脏读、不可重复读、幻读。

事务并发的常见问题

脏读:

所谓脏读就是A事务读取到了B事务还未提交的数据。
图例分析:
在这里插入图片描述

不可重复读:

不可重复读指的是A事务读取到了B事务已经提交的更改数据,在同个时间段内,两次查询结果不一致。
图例分析:
在这里插入图片描述

幻读:

幻读一般是在数据统计的事务上,A事务读取到了B事务提交的新增数据,导致统计结果前后不一致。
图例分析:
在这里插入图片描述

数据库的隔离级别

四种隔离级别简介

四种隔离级别,从程度从低到高依次是读未提交,读已提交,可重复读、串行化。隔离级别越大安全性越高,同时效率也越低,如果设置串行化,那就不存在并发操作了。四种隔离级别对于上述并发下可能出现的三个问题的控制情况可用一张图来描述:
在这里插入图片描述

常见数据库默认隔离级别

不同的数据库默人的隔离级别有差别,Oracle、SQL Server 默认隔离级别是读已提交,Mysql的默认隔离级别是可重复读。

mysql默认级别和实际使用级别的几点说明

对于Mysql实际互联网项目开发一般使用读已提交。其历史原因还得从主从复制说起,主从复制是基于binlog复制的,Mysql在5.0版本以前,binlog只支持STATEMENT这种格式(三种模式:statement:记录的是修改SQL语句;row:记录的是每行实际数据的变更;mixed:statement和row模式的混合),而这种格式在读已提交(Read Commited)这个隔离级别下主从复制是有bug的,在主(master)上执行的顺序为先删后插,而此时binlog为STATEMENT格式,它记录的顺序为先插后删,从(slave)同步的是binglog,因此从机执行的顺序和主机不一致就出现了主从不一致,因此Mysql将可重复读(Repeatable Read)作为默认的隔离级别!
而实际选择读已提交这种隔离级别,有这么几点考虑:

  • 在可重复读隔离级别下,存在间隙锁,导致出现死锁的几率比读已提交大的多;
  • 在可重复读隔离级别下,条件列未命中索引会锁表,而在读已提交隔离级别下,只锁行;
  • 在读已提交隔离级别下,半一致性读(semi-consistent)特性增加了update操作的并发性;

在读已提交这种隔离级别下,主从复制的binlog模式选择row格式,这也是Innodb的创始人建议的方式。

事务并发异常-丢失更新

如果多个线程操作,基于同一个查询结果对表中的记录进行修改,那么后修改的记录将会覆盖前面修改的记录,前面的修改丢失掉了,这就叫丢失更新。
丢失更新分为两类。第一类丢失更新:回滚丢失;第二类丢失更新:覆盖丢失。SQL92没有定义这种现象,标准定义的所有隔离级别都不允许第一类丢失更新发生。
解决丢失更新的办法就是加锁。

悲观锁机制

假定这样的问题是高概率的,最好一开始就锁住,免得更新老出错。

  • 添加共享锁:select * from account lock in share mode;
  • 添加排他锁:select * from account for update;

乐观锁机制

假定这样的问题是小概率的,最后一步做更新的时候再锁住,免得锁住时间太长影响其他人操作。

  • 在表中增加timestamp类型字段,在执行插入或更新时记录最新时间到该字段上;
  • 在修改数据时检查timestamp类型的字段是否改变判断当前的更新基于的查询是否已经过时。

在用户并发数比较少且冲突比较严重的应用系统建议选择悲观锁中的排他锁,其他情况首选乐观锁。

图片文件来自网易云课堂
参考文章:https://www.cnblogs.com/rjzheng/p/10510174.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值