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

本文探讨了一个在新老系统并行时遇到的跨库事务一致性问题,涉及新老数据库双写。提出三种解决方案:1) 使用JTA事务管理器,但可能过于重量级;2) 利用数据库自身同步机制,但不适合多库到一库的场景;3) 建立临时表配合定时批量导入,保证幂等性。文章强调了重试机制在解决分布式事务中的作用。
摘要由CSDN通过智能技术生成

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

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

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

8ceacffe795eb68f54f27dec93b0e7df.png

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

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

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

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

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

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

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

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

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

下面是简单的实现:

34ef438fa3a6bce458031352ff68e0e9.png

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

f68f2add0b68e4f9810432fce46917b7.png

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值