跨服务的数据

简介: 【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);
    }
  }
}

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

目录
相关文章
|
8月前
|
消息中间件 定位技术 数据库
事务跨数据中心处理
事务跨数据中心处理
74 1
|
存储 前端开发 安全
跨页面通信的方式有哪些?
跨页面通信的方式有哪些?
210 0
|
消息中间件 存储 SQL
跨系统数据一致性方案的思考(上)
本文主要意在总结沉淀现有问题解决经验过程,整理解决跨系统数据不一致问题的经验方法。 跨系统数据一致性,比较优秀的解决方案就是微服务化,不同应用系统采用统一数据源方式,这样可以有效避免数据一致性问题。 但是我们很多系统由于历史原因或者业务缘由,导致非服务化情况下,又要采取数据一致性方案。
跨系统数据一致性方案的思考(上)
|
5月前
|
SQL 容灾 关系型数据库
让X不断延伸, 从跨AZ到跨Region再到跨Cloud
本文从“空间”这一维度,聊一聊PolarDB-X在跨空间部署能力上的不断发展和延伸,以及在不同空间范围下的高可用和容灾能力,并着重介绍一下最新的产品能力——GDN(Global Database Network)。
8216 8
|
5月前
|
存储 容灾 Serverless
函数计算产品使用问题之如何实现跨区域协同工作的需求
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
canal 存储 算法
跨系统实时同步数据解决方案
数据量太大,单存储节点存不下,就只能把数据分片存储。
1231 0
|
8月前
|
存储 Web App开发 移动开发
跨页面通信有多少种技术方式可以实现?
跨页面通信有多少种技术方式可以实现?
175 0
|
Web App开发 JavaScript
使用 SharedWorker 进行跨标签通信
sharedWorker 也是一种 worker,sharedWorker 的创建和 webWorker 的创建一样,使用 new 关键字来进行初始化(不能通过代码片段创建),不同的是可以在浏览器不同标签下(同源,后面的跨页面等均是在同源的前提下)使用同一个js url 创建sharedWorker 会复用同一个实例。
480 0
|
运维 API 数据安全/隐私保护
资源中心 - 助您轻松解决跨账号、跨产品、跨地域的资源搜索难题
资源中心为您提供跨账号、跨产品、跨地域的全局资源视图及资源搜索能力。
5504 0
资源中心 - 助您轻松解决跨账号、跨产品、跨地域的资源搜索难题
如何跨场景进行交互
在讲游戏场景的时候,我通常会使用这样的类比:把游戏比作一个房子,场景就是房子里的房间,通常一个房子里有多个房间,而且每个房间都互相连通,可以从一个房间进入到另一个房间。对应的就是可以从游戏中的一个场景进入到另一个场景。
193 0