跨库事务一致性问题的解决方案(例)

简介:

    我们看一个跨库事务一致性的问题,这是一个简单的场景:有新老两个系统,对应新老两套数据库,新数据库采用分库分表的设计,考虑到项目发布之后可能存在风险,采取了新老系统的并行方案。这个系统的业务比较简单:接收来自外部的数据,然后对数据进行核对处理。为了保证新老系统能够并行,在接收数据的时候必须实现双写方案,从而导致了跨库事务的一致性问题。

    下面一幅图展示这一简单的场景

    这里面会存在一个小问题,就是可能存在写入老库成功,但是写入新库失败的场景。

    我们假设出现这种概率的情况是百万分之一,在系统发布的情况下,这种概率可能更高。从目前我们的数据量来看,一天大概5000W,那么出现不一致的数据量在500条。考虑到这个是数据核算系统,不能有一条丢失的情况,否则两边比对结果可能会不一致。所以需要保证一致性。

    这种问题,有以下几种解决方案

1 考虑使用JTA等支持分布式事务的事务管理器

这种方案的优势就是直接有现成的解决方案,一般的j2ee服务器都提供了JTA的相关的实现。比较明显的问题就是解决方案太重量级。一般JTA除了服务器要支持,对应的数据库服务厂商一般也要提供相应的商业支持,主要是提供基于 XAResource  JDBC驱动,这一些商业上的支持,部分是需要付费的。而且使用XA 数据库驱动,本身可能导致一些潜在的问题,尤其是基于不同的数据库厂商的时候。而XA是基于两阶段提交协议,事务管理器为了完成一个事务,需要多次和数据库通信,效率上比较低。

2 考虑使用数据库自身的数据同步机制

    如果新老库的结构基本一样,这种方案还是比较靠谱的。也是比较简单的方案。这种方案的局限性也再次。在本项目中,新库不是一个物理库,而是多个物理库,而老库是一个物理库。如果要用数据库自身的同步机制,涉及到多个库和一个库之间的数据复制。同时由于分表的方案也不一样,导致两边做一个映射的配置,而这个需要在数据库层面进行,逻辑相当的复杂,解决方案成本也比较高。相当于把重要的分库分表的逻辑在数据库这一层重新实现了一份。

    其实这个也带来一个维护问题,一旦我们觉得新系统已经足够稳定。应用程序可以之间在写入库进行切换,把老库的逻辑切掉,从而实现了只写新库的需求。整个过程也不需要进行再次发布。而数据库的方案则需要停掉脚本,在多个地方进行配置。

3 在old库存放相同的两张模型表,一张表用于old库的持久化表,另外一张作为临时表,主要是作为需要同步到到新库的数据。如果已经同步到新库,就删除。如果没有同步到新库就同步到新库。这个过程采用定时机制,每分钟定时提取临时表一定数据量的数据,批量导入到新库。通过努力重试,来保证一致性。而新库则需要保证幂等性,保证数据只会同步过一次。一般情况下,则是通过数据特征标识符来识别,这个一般都是数据的唯一性主键。

    下面是简单的实现:

    这三种方案的主要思想就是 采取重试机制,这个只是分布式事务里面的一种模型,相应的还有两阶段提交,异常恢复补偿等机制。

目录
相关文章
|
架构师 数据库
深入探讨分布式事务:解析跨多个数据库的一致性
在现代应用程序中,分布式系统已经变得越来越普遍,但同时也带来了一系列的挑战。其中之一就是分布式事务管理,它涉及到在多个数据库或服务之间保持一致性和可靠性。本文将深入介绍分布式事务的概念,探讨不同的实现方式以及它们的优缺点。无论您是开发人员、系统管理员还是系统架构师,了解分布式事务是构建稳健分布式系统的关键一步。
|
安全 关系型数据库 MySQL
如何将数据从MySQL同步到其他系统
【10月更文挑战第17天】如何将数据从MySQL同步到其他系统
2229 0
|
人工智能 前端开发 JavaScript
用 通义灵码打造创意 Loading 动画生成器:只需三个词,就能玩出花来!
本文介绍了如何利用“通义灵码”打造一个创意 Loading 动画生成器。作者通过输入“科技感、电波、液体”三个关键词,借助 AI 工具自动生成酷炫的 CSS 动画效果,无需手动编写复杂代码。整个过程高效便捷,只需描述风格关键词,即可生成多种加载动画,并可封装为组件直接使用,极大地提升了开发效率与创意表达。
|
运维 jenkins 持续交付
自动化运维之路:构建高效CI/CD流水线
在软件开发的快节奏中,持续集成和持续部署(CI/CD)流水线是提升效率、保障质量的关键。本文将引导你理解CI/CD流水线的重要性,并手把手教你如何搭建一个高效的自动化运维系统。通过实际代码示例,我们将一步步实现从代码提交到自动测试、部署的全流程自动化,确保软件交付过程既快速又可靠。
1305 5
|
前端开发 Java API
Swagger接口文档 —— 手把手教学,全方位超详细小白能看懂,百分百能用Java版
本文提供了一份详细的Swagger接口文档生成工具的使用教程,包括了导入依赖、配置类设置、资源映射、拦截器配置、Swagger注解使用、生成接口文档、在线调试页面访问以及如何设置全局参数(如token),旨在帮助Java开发者快速上手Swagger。
13148 0
Swagger接口文档 —— 手把手教学,全方位超详细小白能看懂,百分百能用Java版
|
存储 缓存 安全
理解GET和POST区别的全面指南
![理解GET和POST区别的全面指南](https://assets.echoapi.com/upload/user/222825349921521664/log/fb5d7a29-f85c-46e0-835c-a8fdc925ec73.webp) 本文详细解析了REST API中GET和POST方法的区别。GET用于从服务器获取数据,参数在URL中传递,适合查询;POST用于发送数据以创建或更新资源,数据放在请求体中,适合提交表单。两者在安全性、缓存、幂等性等方面有显著差异,理解这些区别有助于设计高效且安全的API。
1048 11
|
jenkins Java 持续交付
软件开发自动化程度的不断提高,持续集成(CI)和持续部署(CD)成为现代软件开发的重要组成部分
随着软件开发自动化程度的不断提高,持续集成(CI)和持续部署(CD)成为现代软件开发的重要组成部分。本文以电商公司为例,介绍如何使用 Jenkins 自动发布 Java 代码,包括安装配置、构建脚本编写及自动化部署等步骤,帮助团队实现高效稳定的软件交付。
296 3
|
监控 中间件 UED
中间件数据传输数据一致性
中间件在跨系统数据传输中确保一致性至关重要,采用事务处理、数据校验和验证、分布式一致性协议(如Raft、Paxos)、数据复制与同步、错误处理及重试机制、监控日志记录和选择合适的一致性级别(如强一致或最终一致)等策略,能有效提高传输的可靠性和数据一致性。
425 2
|
缓存 Java Spring
《SpringBoot启动流程一》:万字debug梳理SpringBoot如何加载并处理META-INF/spring.factories文件中的信息
1、SpringBoot如何加载并处理spring.factories中的文件? 2、加载出的spring.factories文件中的内容如何排序? 3、多个spring.factories文件内容重复怎么处理?
1736 0
《SpringBoot启动流程一》:万字debug梳理SpringBoot如何加载并处理META-INF/spring.factories文件中的信息
|
消息中间件 Java 数据库
面试题:如何保证三个数据库之间的数据一致性,如服务突然宕机
面试题:如何保证三个数据库之间的数据一致性,如服务突然宕机
489 0