数据库读写分离和事务的关系

问题:

数据库是读写分离架构,事务中的读操作没有强制走主库,这个时候是不是会有读延迟,读的操作比写操作慢,导致没有及时读到其他事务写的数据

总结

  • 读写分离和主从架构是一个概念,主库写,从库读,主从同步
  • 主从同步分成异步、半同步两种方式
  • 产生事务时,会强制走主库,事务中的读操作和写操作都会强制走主库

https://blog.csdn.net/qq_46371374/article/details/149513968

https://www.cnblogs.com/wxg1990/articles/19465535

https://www.cnblogs.com/88223100/p/On-the-pitfalls-of-MySQL-read-write-separation-and-corresponding-solutions.html

https://www.jianshu.com/p/8b43bbf52dc6

https://zhuanlan.zhihu.com/p/29166694


在读写操作处于同一事务时,读写分离通过事务绑定主库强制读主库策略运作,确保事务的原子性和一致性。以下是具体运作机制和解决方案:

一、核心运作机制

  1. 事务绑定主库
    当事务开始时,所有读写操作(包括SELECT查询)均路由到主库执行。例如:
    • 用户提交订单(写操作)和查询订单状态(读操作)在同一个事务中,系统会强制将查询请求也发送到主库,避免从库数据延迟导致的不一致。
    • 事务结束后,后续非事务性读操作可重新路由到从库。
  2. 主从数据同步
    主库执行完事务后,通过异步复制 (默认)或半同步复制 (可选)将数据变更同步到从库:
    • 异步复制:主库写入binlog后立即返回成功,不等待从库确认。性能高,但可能丢失少量数据(如主库崩溃时未同步的日志)。
    • 半同步复制:主库至少等待一个从库确认收到binlog后才返回成功。牺牲少量性能,但提升数据安全性。

二、事务中的读写分离解决方案

方案1:强制读主库(推荐)
  • 适用场景:对数据一致性要求极高的业务(如支付、订单状态查询)。
  • 实现方式
    • 代码层面 :通过注解或框架配置,强制事务中的读操作走主库。例如:

      复制代码

      java

      复制代码
      `@Transactional // 开启事务
      public void submitOrder(Order order) {
          orderMapper.insert(order); // 写操作(主库)
          Order result = orderMapper.selectById(order.getId()); // 强制读主库
      }`
    • 中间件层面:使用ShardingSphere等中间件,自动识别事务中的读操作并路由到主库。

方案2:同步复制(牺牲性能保一致)
  • 适用场景:金融交易等绝对不允许数据丢失的场景。

  • 配置示例 (MySQL):

    复制代码

    ini

    复制代码
    `# 主库配置
    sync_binlog=1          # 每次事务提交前将binlog刷盘
    innodb_flush_log_at_trx_commit=1 # 每次事务提交前将redo log刷盘
    
    # 从库配置(半同步复制)
    rpl_semi_sync_master_enabled=1
    rpl_semi_sync_master_wait_for_slave_count=1`
  • 缺点:主库响应时间增加,吞吐量下降。

方案3:延迟读取(折中方案)
  • 适用场景:对实时性要求不高,但需避免主从延迟的业务(如用户评论展示)。
  • 实现方式
    • 写操作后,延迟一段时间(如500ms)再执行读操作,给从库留出同步时间。
    • 通过缓存(如Redis)暂存写操作结果,读操作优先从缓存获取。

三、关键问题与对策

  1. 主从延迟导致的数据不一致
    • 问题:事务提交后,从库未同步完成,此时读从库会得到旧数据。
    • 对策
      • 强制读主库(方案1)。
      • 使用**GTID(全局事务标识)**追踪事务同步状态,确保读操作只发生在已同步的从库上。
  2. 事务跨主从库的分布式事务问题
    • 问题:若事务涉及多个主库或跨库操作,需保证ACID特性。
    • 对策
      • 使用XA协议 (两阶段提交)或TCC模式(补偿事务)实现分布式事务。
      • 避免跨库事务,通过业务设计将操作限制在单个库内。

四、实际案例

电商平台订单支付场景

  1. 用户提交订单(写主库)。
  2. 系统扣减库存(写主库)。
  3. 查询订单状态(强制读主库,避免从库延迟)。
  4. 支付成功后,异步更新从库数据(如用户积分、商品销量)。

技术栈

  • 数据库:MySQL(主从复制+半同步)。
  • 中间件:ShardingSphere(读写分离+事务路由)。
  • 缓存:Redis(暂存热点数据,减轻数据库压力)。
相关推荐
来来走走几秒前
rocky linux 9.7安装mysql 8.4+
linux·数据库·mysql
怣5015 分钟前
MySQL多表连接完全指南:内连接与外连接超详细讲解
数据库·sql·mysql
专注VB编程开发20年28 分钟前
python图片验证码识别selenium爬虫--超级鹰实现自动登录,滑块,点击
数据库·python·mysql
智商偏低29 分钟前
Postgresql导入几何数据(shp,geojson)的几种方式
数据库·postgresql
我是Superman丶1 小时前
在 PostgreSQL 中使用 JSONB 类型并结合 MyBatis-Plus 实现自动注入,主要有以下几种方案
数据库·postgresql·mybatis
五度易链-区域产业数字化管理平台1 小时前
「五度易链」行业标准信息数据库简介
大数据·数据库
霖霖总总1 小时前
[小技巧65]深入 InnoDB 页的逻辑存储结构:16KB 页的逻辑全景解析
数据库·mysql
数研小生1 小时前
关键词搜索京东列表API技术对接指南
大数据·数据库·爬虫
野犬寒鸦2 小时前
从零起步学习并发编程 || 第五章:悲观锁与乐观锁的思想与实现及实战应用与问题
java·服务器·数据库·学习·语言模型
VX:Fegn08952 小时前
计算机毕业设计|基于springboot + vue云租车平台系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计