zoukankan      html  css  js  c++  java
  • 跨库事务一致性问题的解决方式(例)

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

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

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

        我们假设出现这样的概率的情况是百万分之中的一个,在系统公布的情况下,这样的概率可能更高。从眼下我们的数据量来看,一天大概5000W。那么出现不一致的数据量在500条。

    考虑到这个是数据核算系统,不能有一条丢失的情况,否则两边比对结果可能会不一致。所以须要保证一致性。

        这样的问题,有以下几种解决方式

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

    这样的方案的优势就是直接有现成的解决方式,一般的j2eeserver都提供了JTA的相关的实现。比較明显的问题就是解决方式太重量级。一般JTA除了server要支持,相应的数据库服务厂商一般也要提供相应的商业支持。主要是提供基于 XAResource  JDBC驱动,这一些商业上的支持,部分是须要付费的。

    并且使用XA 数据库驱动,本身可能导致一些潜在的问题,尤其是基于不同的数据库厂商的时候。而XA是基于两阶段提交协议。事务管理器为了完毕一个事务,须要多次和数据库通信,效率上比較低。

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

        假设新老库的结构基本一样,这样的方案还是比較靠谱的。

    也是比較简单的方案。

    这样的方案的局限性也再次。在本项目中。新库不是一个物理库。而是多个物理库,而老库是一个物理库。

    假设要用数据库自身的同步机制,涉及到多个库和一个库之间的数据复制。同一时候因为分表的方案也不一样,导致两边做一个映射的配置,而这个须要在数据库层面进行,逻辑相当的复杂。解决方式成本也比較高。

    相当于把重要的分库分表的逻辑在数据库这一层又一次实现了一份。

        事实上这个也带来一个维护问题。一旦我们认为新系统已经足够稳定。

    应用程序可以之间在写入库进行切换,把老库的逻辑切掉,从而实现了仅仅写新库的需求。整个过程也不须要进行再次公布。而数据库的方案则须要停掉脚本,在多个地方进行配置。

    3 在old库存放同样的两张模型表。一张表用于old库的持久化表。另外一张作为暂时表,主要是作为须要同步到到新库的数据。

    假设已经同步到新库。就删除。假设没有同步到新库就同步到新库。这个过程採用定时机制,每分钟定时提取暂时表一定数据量的数据。批量导入到新库。

    通过努力重试,来保证一致性。而新库则须要保证幂等性。保证数据仅仅会同步过一次。普通情况下,则是通过数据特征标识符来识别,这个一般都是数据的唯一性主键。

        以下是简单的实现:

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

  • 相关阅读:
    【IT学习资源】2013.10.30
    【转载】 Bash之read命令
    【书本目录】 -- ABS(advanced bash scripts)
    【转载】vSphere的使用
    【转载】 Linux命令 -- tr 转换字符
    【转载】Oracle的日常监控脚本
    【转载】Nginx基础:6.webcache缓存服务
    大学记忆(3)[三国杀(终)]
    大学记忆(1)[记忆之殇]
    大学记忆(2)[计算机]
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5397576.html
Copyright © 2011-2022 走看看