数据库分库分表之后,你是如何解决事务问题?[通俗易懂]

数据库分库分表之后,你是如何解决事务问题?[通俗易懂]我们需要接受失望,因为它是有限的;我们不会失去希望,因为它是无穷的。 一、概述 随着时间和业务的发展,数据库中表的数据量会越来越大,相应地,数据操作,增删改查的开销也会越来越大。因此,把其中一些大表进

数据库分库分表之后,你是如何解决事务问题?

我们需要接受失望,因为它是有限的;我们不会失去希望,因为它是无穷的。
一、概述

随着时间和业务的发展,数据库中表的数据量会越来越大,相应地,数据操作,增删改查的开销也会越来越大。因此,把其中一些大表进行拆分到多个数据库中的多张表中。
本篇文章是基于非事务消息的异步确保的方式来完成分库分表中的事务问题。

二、需要解决问题

2.1 原有事务

由于分库分表之后,新表在另外一个数据库中,如何保证主库和分库的事务性是必须要解决的问题。

解决办法:通过在主库中创建一个流水表,把操作数据库的逻辑映射为一条流水记录。当整个大事务执行完毕后(流水被插入到流水表),然后通过其他方式来执行这段流水,保证最终一致性。
file

2.2 流水

所谓流水,可以理解为一条事务消息

上面通过在数据库中创建一张流水表,使用一条流水记录代表一个业务处理逻辑,因此,一个流水一定是能最终正确执行的.因此,当把一段业务代码提取流水中必须要考虑到:

  • 流水延迟处理性。流水不是实时处理的,而是用过流水执行器来异步执行的。因此,如果在原有逻辑中,需要特别注意后续流程对该流水是不是有实时依赖性(例如后续业务逻辑中会使用流水结果来做一些计算等)。

  • 流水处理无序性。保证即使后生成的流水先执行,也不能出现问题。

  • 流水最终成功性。对每条插入的流水,该条流水一定要保证能执行成功

因此,提取流水的时候:

  • 流水处理越简单越好

  • 流失处理依赖越少越好

  • 提取的流水在该业务逻辑中无实时性依赖
    file

2.4 流水处理完成

因为流水表是放在原数据库中,而流水处理完成后是操作分库,如果分库操作完成去更新老表流水消息,那么又是夸库事务,如何保证流水状态的更新和分库也是在一个事务的?

解决办法是:在分库中创建一个流水表,当流失处理完成以后,不是去更新老表状态,而是插入分库流水表中、

这样做的好处:

  • 一般会对流水做唯一索引,那么如果流水重复多次执行的时候,插入分库流水表的时候肯定由于唯一索引检测不通过,整个事务就会回滚(当然也可以在处理流水事前应该再做一下幂等性判断)

  • 这样通过判断主库流水是否在分库中就能判断一条流水是否执行完毕
    file
    三、流水处理器基本框架


流水处理器其实不包含任何业务相关的处理逻辑,核心功能就是:

  • 通知业务接入方何时处理什么样的流水

  • 检验流水执行的成功

注:流水执行器并不知道该流水表示什么逻辑,具体需要业务系统去识别后去执行相对应业务逻辑。
file

3.1 流水执行任务

流水处理调度任务就是通过扫描待处理的流水,然后通知业务系统该执行哪一条流水。

示意图如下:
file

3.2 流水校验任务

流水校验任务就是要比较主库和分库中的流水记录,对执行未成功的流水通知业务系统进行重新处理,如果多次重试失败则发出告警。

流程示意图:
file
四、为什么不用事务消息

由于是既有项目(互联网金融,所以是绝对不容忍有任何消息丢失或者消息处理失败)进行改造,不使用事务消息有1个原因

  • 需要额外引入消息队列,增加系统的复杂度,而且也需要额外的逻辑保证和消息队列通讯失败的时候处理

  • 其实1不算是主要原因,而是因为事务消息需要手动的commit和rollback(使用数据库不需要),那么问题来了,spring中事务是有传递性的,那我们事务消息何时提交又是个大问题,例如 A.a()本来就是一个事务, 但是另外一个事务B.b()中又调用了A.a() 那事务消息提交是放在A.a()还是B.b()中呢?

本文由博客一文多发平台 OpenWrite 发布!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/7572.html

(0)
上一篇 2023-03-18
下一篇 2023-03-18

相关推荐

  • Python变量命名规则及常见问题

    Python变量命名规则及常见问题在Python中,变量的命名规则是极其灵活的。下面我们来看一下Python变量的命名规则。

    2024-04-11
    63
  • 一文掌握Redis的三种集群方案「建议收藏」

    一文掌握Redis的三种集群方案「建议收藏」在开发测试环境中,我们一般搭建Redis的单实例来应对开发测试需求,但是在生产环境,如果对可用性、可靠性要求较高,则需要引入Redis的集群方案。虽然现在各大云平台有提供缓存服务可以直接使用,但了解一

    2023-02-06
    144
  • mongodb intellishell studio 3T shell 操作[通俗易懂]

    mongodb intellishell studio 3T shell 操作[通俗易懂]当需要在mongo中多表查询或者关联查询并导出结果当时候,可以用类似script语法。 特别注意的是,如果采用3T的导出操作export,只有最后语句是查询语句才能导出 var ids = [] d…

    2023-03-05
    161
  • 图解MySQL | [原理解析] Adaptive Hash Index 是如何建立的[通俗易懂]

    图解MySQL | [原理解析] Adaptive Hash Index 是如何建立的[通俗易懂]转载自公众号:图解MySQL Adaptive Hash Index(以下简称 AHI)估计是 MySQL 的各大特性中,大家都知道名字但最说不清原理的一个特性。本期图解我们为大家解析一下 AHI …

    2023-01-28
    133
  • windows7安装mongodb_Windows休眠

    windows7安装mongodb_Windows休眠1. 在Windows环境安装 1.1 MongoDB下载 要在Windows上安装MongoDB,首先打开MongoDB官网:https://www.mongodb.com/download-cen

    2022-12-21
    131
  • Python Weakref简介及使用方法

    Python Weakref简介及使用方法在Python中,所有的对象都会有一个引用计数,即记录有多少个变量引用了这个对象。当引用计数为0时,Python解释器就会将其回收。但是,有些时候,我们希望对象在某个时刻被回收,而不是等到引用计数为0时才回收。比如,当我们需要大量创建对象时,频繁创建和销毁这些对象会占用很多时间和内存。

    2024-05-31
    50
  • 数据库规范化设计_数据库案例分析

    数据库规范化设计_数据库案例分析操作异常 修改异常、插入异常、删除异常 数据依赖 数据间的联系 函数依赖FD 属性捡的联系,最基本的数据依赖 若确定X,则可以唯一的确定Y,则称Y依赖于X记X->Y 若X->Y,且Y是X的

    2023-03-04
    153
  • Python爬虫:如何高效获取网页数据

    Python爬虫:如何高效获取网页数据随着互联网的高速发展,数据爬取在各行各业越来越重要。Python爬虫作为一种高效获取网页数据的工具,被广泛应用于数据分析、大数据处理等领域。本文章将详细讲解Python爬虫获取网页数据的方法和技巧。

    2024-07-29
    22

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注