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

一、概述

随着时间和业务的发展,数据库中表的数据量会越来越大,相应地,数据操作,增删改查的开销也会越来越大。因此,把其中一些大表进行拆分到多个数据库中的多张表中。

本篇文章是基于非事务消息的异步确保的方式来完成分库分表中的事务问题。

二、需要解决问题

2.1 原有事务

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

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

2.2 流水

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

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

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

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

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

因此,提取流水的时候:

流水处理越简单越好

流失处理依赖越少越好

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

2.4 流水处理完成

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

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

这样做的好处:

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

这样通过判断主库流水是否在分库中就能判断一条流水是否执行完毕

三、流水处理器基本框架

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

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

检验流水执行的成功

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

3.1 流水执行任务

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

示意图如下:

3.2 流水校验任务

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

流程示意图:

四、为什么不用事务消息

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

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

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

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

mysql分库分表事务控制_数据库分库分表之后,你是如何解决事务问题?相关推荐

  1. mysql分库分表按时间_数据库分库分表思路

    一. 数据切分 关系型数据库本身比较容易成为系统瓶颈,单机存储容量.连接数.处理能力都有限.当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库.优化索引,做很多操作时性能仍下降 ...

  2. navicat 表合并查询_数据库两个表合并命令

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  3. mysql分库分表风险_数据库分库分表存在的问题及解决方案

    读写分离分散了数据库读写操作的压力,但是没有分散存储压力,当数据库的数据量达到千万甚至上亿条的时候,单台数据库服务器的存储能力就会达到瓶颈,主要体现在以下几个方面: 数据量太大,读写性能会下降,即使有 ...

  4. Django 应用分库,数据迁移成功,数据库没有生成表

    Django 应用分库,数据迁移成功,数据库没有生成表 背景:不同应用对应不同数据库,在迁移数据成功后,数据库没有生成表 Django 官网:https://docs.djangoproject.co ...

  5. (转)【mysql元数据库】使用information_schema.tables查询数据库和数据表信息 ---数据记录大小统计...

    转:https://www.cnblogs.com/ssslinppp/p/6178636.html https://segmentfault.com/q/1010000007268994?_ea=1 ...

  6. oracle数据库超大表名更改,oracle如何修改表名_数据库,oracle,修改表名

    Oracle建表语句是什么_数据库 Oracle建表语句是CREATE TABLE tablename(column_name datatype).其中tablename是要创建的表名,column_ ...

  7. 数据透视表 字段交叉_删除数据透视表的计算字段的宏

    数据透视表 字段交叉 Have you ever recorded a macro to remove pivot table calculated fields? Just turn on the ...

  8. nodejs mysql 分表_数据库分库分表学习

    大型网站数据库分库分表 分库分表方案: 垂直&水平 1.什么是垂直拆分? 指的是将一个包含了很多表的数据库,根据表的功能的不同,拆分为多个小的数据库,每个库中包含部分表. .垂直拆分的另外2种 ...

  9. 分区和分片的区别_数据库的分表、分库、分片和分区等区别

    一.Sharding(分片) Sharding 是把数据库横向扩展(Scale Out)到多个物理节点上的一种有效的方式,其主要目的是为突破单节点数据库服务器的 I/O 能力限制,解决数据库扩展性问题 ...

最新文章

  1. JavaScript碎片—函数闭包(模拟面向对象)
  2. altair feko+winprop 2020中文版
  3. Apache ZooKeeper -从初始化到对外提供服务的过程解析( 集群模式 )
  4. 列车停站方案_4月10日零时起阜阳高铁、铁路大调图!最新列车时刻表来了!看看有没有你经常乘坐的列车?...
  5. Entity Framework Core Lolita
  6. 数据结构与算法--力扣108题将有序数组转换为二叉搜索树
  7. 【C++ 学习笔记】:STL-map
  8. mac 修改conda镜像 condarc_win10 修改anaconda源
  9. 【华为云实战开发】13.如何在云端快速搭建python网站
  10. android apk 防止反编译技术加壳技术(转)
  11. 【画图专题】sns.heatmap的用法简介
  12. PHP自定义状态码数组
  13. LINUX下安装svn客户端
  14. 检索 COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 8000401a 因为配置标识不正确
  15. 原来这就是公文写作总结类模板和计划类模板
  16. IDLE Help | 汉化
  17. 洛谷刷题笔记5.p1116 车厢重组
  18. DevOps在证券互联网研发中的应用与实践
  19. 2023最新彩虹易支付源码免授权2.0版前台模板美化/用户中心美化
  20. android 安全加固总结报告,Android应用本地代码的安全加固及安全性评估

热门文章

  1. 【STM32】学习笔记RTC日历基础应用问题分析
  2. 【体验】18650锂电池充电器体验,功能测试,18650充电测试
  3. matlab-画个拱桥和倒影?
  4. 微软称电脑系统识别能力已经超越了人类
  5. Http压测工具wrk使用指南
  6. v-show和v-if的区别
  7. 我的Java开发学习之旅------gt;Base64的编码思想以及Java实现
  8. 关于 xml 库运行时的segmentation fault 问题
  9. Spring3MVC+Mybatis3.1框架下的事务
  10. Cisco easy *** basic ASA