跨服务的数据

简介: 【10月更文挑战第29天】

在微服务架构中,保证跨服务的数据操作一致性是一个挑战,因为服务可能分布在不同的数据库甚至不同的数据中心。以下是几种常见的策略来保证跨服务的数据一致性,以及相应的代码示例:

1. 两阶段提交(2PC)

两阶段提交是一种保持分布式系统一致性的协议,它分为准备阶段和提交阶段。

代码示例(概念性伪代码):

// 服务A和B的数据库事务开始
beginTransactionA();
beginTransactionB();

try {
   
  // 服务A的数据库操作
  serviceADatabase.update(...);

  // 服务B的数据库操作
  serviceBDatabase.update(...);

  // 提交事务
  commitTransactionA();
  commitTransactionB();
} catch (error) {
   
  // 回滚事务
  rollbackTransactionA();
  rollbackTransactionB();
  throw error;
}

2. 补偿事务(TCC)

补偿事务涉及到尝试执行业务操作(Try),如果成功则确认(Confirm),如果失败则补偿(Cancel)。

代码示例(概念性伪代码):

// 尝试阶段
try {
   
  serviceADatabase.try(...);
  serviceBDatabase.try(...);
} catch (error) {
   
  // 补偿阶段
  serviceADatabase.cancel(...);
  serviceBDatabase.cancel(...);
  throw error;
}

// 确认阶段
serviceADatabase.confirm(...);
serviceBDatabase.confirm(...);

3. 事件驱动和最终一致性

在事件驱动架构中,服务之间的交互是通过事件来协调的。服务会监听事件并相应地更新自己的数据库,以达到最终一致性。

代码示例(Node.js使用MQ):

// 服务A产生事件
function handleOrderCreation(order) {
   
  // ...
  produceEvent('order_created', order);
}

// 服务B监听事件并处理
function onOrderCreated(order) {
   
  // 更新服务B的数据库
  serviceBDatabase.updateOrder(order);
}

// 设置事件监听
eventBus.subscribe('order_created', onOrderCreated);

4. 分布式事务管理器

使用如Apache Kafka、RabbitMQ等消息队列,或者分布式事务管理器如Seata来协调跨服务的事务。

代码示例(使用Seata的概念性伪代码):

const {
    GlobalTransactionContext } = require('seata-nodejs');

// 开始全局事务
GlobalTransactionContext.beginTransaction();

try {
   
  // 执行服务A的数据库操作
  serviceADatabase.update(...);

  // 执行服务B的数据库操作
  serviceBDatabase.update(...);

  // 提交全局事务
  GlobalTransactionContext.commit();
} catch (error) {
   
  // 回滚全局事务
  GlobalTransactionContext.rollback();
  throw error;
}

5. 本地消息表

在服务内部使用消息队列来确保操作的顺序性和一致性。

代码示例(Node.js伪代码):

// 本地消息表
const messageQueue = [];

function processOrder() {
   
  // 执行订单服务的数据库操作
  serviceADatabase.update(...);

  // 将消息放入本地消息表
  messageQueue.push({
    eventType: 'order_updated', data: order });

  // 异步处理消息表中的消息
  processLocalMessages();
}

function processLocalMessages() {
   
  while (messageQueue.length > 0) {
   
    const message = messageQueue.shift();

    // 根据事件类型执行相应的操作
    if (message.eventType === 'order_updated') {
   
      serviceBDatabase.update(message.data);
    }
  }
}

在实际应用中,选择哪种策略取决于业务需求、系统复杂性、可接受的一致性级别和容错能力。通常,最终一致性模型更适用于分布式系统,因为它可以提供更好的可用性和可扩展性。然而,在需要强一致性的场景下,两阶段提交或补偿事务可能更合适。每种策略都有其权衡,因此在设计系统时应仔细考虑这些因素。

目录
相关文章
|
7月前
|
消息中间件 定位技术 数据库
事务跨数据中心处理
事务跨数据中心处理
72 1
|
存储 前端开发 安全
跨页面通信的方式有哪些?
跨页面通信的方式有哪些?
203 0
|
消息中间件 存储 SQL
跨系统数据一致性方案的思考(上)
本文主要意在总结沉淀现有问题解决经验过程,整理解决跨系统数据不一致问题的经验方法。 跨系统数据一致性,比较优秀的解决方案就是微服务化,不同应用系统采用统一数据源方式,这样可以有效避免数据一致性问题。 但是我们很多系统由于历史原因或者业务缘由,导致非服务化情况下,又要采取数据一致性方案。
跨系统数据一致性方案的思考(上)
|
4月前
|
SQL 容灾 关系型数据库
让X不断延伸, 从跨AZ到跨Region再到跨Cloud
本文从“空间”这一维度,聊一聊PolarDB-X在跨空间部署能力上的不断发展和延伸,以及在不同空间范围下的高可用和容灾能力,并着重介绍一下最新的产品能力——GDN(Global Database Network)。
8159 8
|
canal 存储 算法
跨系统实时同步数据解决方案
数据量太大,单存储节点存不下,就只能把数据分片存储。
1226 0
|
7月前
|
存储 Web App开发 移动开发
跨页面通信有多少种技术方式可以实现?
跨页面通信有多少种技术方式可以实现?
169 0
|
Web App开发 JavaScript
使用 SharedWorker 进行跨标签通信
sharedWorker 也是一种 worker,sharedWorker 的创建和 webWorker 的创建一样,使用 new 关键字来进行初始化(不能通过代码片段创建),不同的是可以在浏览器不同标签下(同源,后面的跨页面等均是在同源的前提下)使用同一个js url 创建sharedWorker 会复用同一个实例。
477 0
如何跨场景进行交互
在讲游戏场景的时候,我通常会使用这样的类比:把游戏比作一个房子,场景就是房子里的房间,通常一个房子里有多个房间,而且每个房间都互相连通,可以从一个房间进入到另一个房间。对应的就是可以从游戏中的一个场景进入到另一个场景。
186 0
|
存储 运维 容灾
阿里云跨可用区备份容灾解决方案详解
本文结合阿里云的可用区资源及功能延展了一种更新的跨可用区容灾解决方案,并选型了一款对企业来说性价比较高的产品进行分析分享,希望对大家有帮助。
|
存储 编解码 JSON
Elasticsearch 跨网络、跨集群同步选型指南
1、两个同步实战问题 问题1:我想从目前的阿里云上6.7版本的es商业版,迁移到自己的7.10的自建环境,证书不一样,无法远程 无法ccr,有没有实时同步的工具呀?还是只能用logstash ? 问题2:es 2个索引数据同步有什么组件或者方案吗?
1150 0
Elasticsearch 跨网络、跨集群同步选型指南
下一篇
DataWorks