当前位置: 首页 > news >正文

对于数据库的并发控制的一些思考

1、脏读、脏写以及解决办法
类似于多线程同步问题,在数据库中也有这样的问题,多个用户同时读或者写同一块数据,这就有了竞争,可能会造成数据的不一致。在操作系统中是可以使用加锁来解决的,但是为了性能问题,大多数情况下都会考虑不加锁或者使用读写锁这种较快的锁。在数据库中也类似,我们可以选择加锁,但是同时也会寻求较好的别的方案。
目前主流的数据库的解决方案是这样的:

  • 对于脏写,会加锁,这个不可避免。但是会加较小粒度的锁,比如行级锁。从而有效增加并行度。
  • 对于脏读,要是加锁的话会导致大的读严重卡住数据库。所以我们不能加锁。为了不加锁的情况下还能读到有效的数据,就引出了快照。每次读的时候都直接读当时的快照(如果当时有写在修改数据,这个快照就是较旧的数据),从而确保不会读到事务正在修改的数据。
    所以说对于解决脏读脏写,其实就是使用写加锁,以及维持一个旧数据的快照以供读操作。

2、可重复读
有这么一种情况,A的事务要读两次数据,第一次读的是100,然后在第二次读之前,B执行了一个事务将值修改为了200,这样A读出来的就是200,造成了前后不一致。但是这个一般影响不大,但是在某些场景下会有问题,比如拷贝数据的时候,或者查询分析数据时等等。这些场景的前后不一致会导致失败。
在这样的场景下,我们就要确保一次事务的前后都是能读到一致的数据。解决办法同样是使用快照,这就引入了MVCC(多版本并发控制Multi-veision Concurrency Control)来控制数据的事务号,确保事务读可以读到它能读的数据。在每个事务执行过程中都读着同一份快照,从始至终都是这样,确保可以重复读到一样的数据。

那每次都新建一个快照也是比较大的损耗,也有一部分优化,目的是降低索引树的更新。即每次新建快照都复制一个索引树,因为大部分事务其实修改都不多,所以树之有一部分是新的,这些用新的节点。剩余的都是用引用指向旧的点即可。这类似于写时复制,可以大大降低性能损耗。
另一种办法是将同一对象的不同版本放在一个内存页面中,从而避免更新索引。但是缺点显而易见,会有较大内存碎片。

3、幻读
设想这样一个场景,A和B同时申请一个会议室的使用权,在可重复读场景下,两个事务执行前都创建了快照,并且要添加一个信息,但是这个不是一种行修改,而是新建,这就使得加锁无从可加。从而导致一种错误的结果,这叫做幻读或者写倾斜。
为了解决这样的问题,我们需要更强的隔离要求,串行化。即严格控制事务执行顺序,类似单线程执行。

http://www.gsyq.cn/news/44168.html

相关文章:

  • 2025年11月高能量密度锂电池厂家排行榜:五家技术路线深度对比
  • 2025年11月超声波清洗机厂家榜单:性能参数与口碑评分全解析
  • 2025年11月铝合金凉亭品牌对比榜:从别墅到餐厅的全场景解决方案
  • 实用指南:MySQL笔记---C/C++访问MySQL数据库
  • 山石CLI抓包
  • 点击领取文章
  • Buildroot使用说明
  • Paper Reading:Neural Prototype Trees for Interpretable Fine-grained Image Recognition
  • 2025.11 NOIP 集训模拟赛选记
  • 2025.11.8 测试
  • C# 变量详解:从基础概念到高级应用 - 实践
  • CF285G AGC003D
  • 用 Kubernetes 原生机制取代 Nacos 注册中心:可行性、代价与边界
  • 获取设置开发授权激活统信uos
  • 基于单片机的智能洗碗机设计 - 指南
  • 赫尔曼黑塞《德米安》—生活之难,难在直面内心的自己
  • 安装openjdk21
  • 暴字迹
  • 体验CodeBuddy免费领取轻量云服务器
  • TOYOTA SYSTEMS Programming Contest 2025(AtCoder Beginner Contest 431)
  • VMware开机自启虚拟机及报错修复
  • AI浪潮下的冷思考:机遇、风险与未来
  • 算起计算器APP,好看好用的多功能计算器
  • 鸿蒙语言基础学习经验分享:从困惑到渐入佳境
  • 修复达梦EFCore驱动布尔类型兼容问题
  • 2021:【例4.6】最大公约数
  • 考试(高二上)
  • 详细介绍:风机水泵改软起技术分析(XX公司)
  • Entry HDL原理图导出料单设置步骤
  • Allegro:如何手动在PCB中添加元器件以及删除元器件