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

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

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

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

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

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

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

http://www.jsqmd.com/news/35374/

相关文章:

  • 2025年11月环保板材品牌榜单:十强横向评价让选材不再纠结
  • 2025年11月纸杯厂家对比评测榜:金豪领衔产能与认证全维度排行
  • 2025年11月高能量密度锂电池厂家排行榜:五家技术路线深度对比
  • 2025年11月超声波清洗机厂家推荐榜:五强对比评测与选购指南
  • 2025年11月环保板材品牌排行:从ENF到高定全维度评测
  • 2025年11月超声波清洗机厂家推荐榜:性能价格服务三维评测
  • 2025年11月狐臭产品推荐评测:苗母堂专利技术与四款热销单品对比
  • 2025年11月超声波清洗机厂家榜单:性能参数与口碑评分全解析
  • 2025年11月狐臭产品推荐榜:用户实测好评率与三重修护机制解析
  • 2025年11月新疆旅行社排行榜:真实评价梳理避坑指南
  • 2025年11月牙齿矫正医院推荐:五强对比评测
  • 2025年11月超声波清洗机厂家推荐榜:五家主流厂商性能与价格横向评测
  • 2025年11月铝合金凉亭品牌对比榜:从别墅到餐厅的全场景解决方案
  • 2025年11月纸杯厂家推荐:产能规模与认证体系全维度对比榜
  • 给大家推荐一个特别好的 F.Q 博客
  • AI元人文的终极形态:从“系统蓝图”到“指导智慧”的升维
  • 2025.11.8总结
  • 设备版本升级-思科NXOS
  • (1)apply和transform
  • 跟着狂神学习Java基础打卡第二天
  • 实用指南:MySQL笔记---C/C++访问MySQL数据库
  • 山石CLI抓包
  • 点击领取文章
  • Kotlin 协程之 Flow 操作符大全 - 实践
  • 使用DS18B20过程中的一些坑
  • Buildroot使用说明
  • Buildroot使用说明
  • 实用指南:神经网络常用激活函数公式
  • 实用指南:神经网络常用激活函数公式
  • 单片机进入 B. 中断无限循环异常消除方法