CAP
CAP docs看到更多详细资料。
CAP 视频教程,学习如何在项目中集成CAP。
●GitHub源码:https://github.com/dotnetcore/cap
●示例代码:https://github.com/dotnetcore/CAP/tree/master/samples

CAP 事务

CAP 不直接提供开箱即用的基于 DTC 或者 2PC 的分布式事务,相反我们提供一种可以用于解决在分布式事务遇到的问题的一种解决方案。
在分布式环境中,由于涉及通讯的开销,使用基于2PC或DTC的分布式事务将非常昂贵,在性能方面也同样如此。另外由于基于2PC或DTC的分布式事务同样受CAP定理的约束,当发生网络分区时它将不得不放弃可用性(CAP中的A)。
针对于分布式事务的处理,CAP 采用的是“异步确保”这种方案。

异步确保

异步确保这种方案又叫做本地消息表,这是一种经典的方案,方案最初来源于 eBay,参考资料见段末链接。这种方案目前也是企业中使用最多的方案之一。
相对于 TCC 或者 2PC/3PC 来说,这个方案对于分布式事务来说是最简单的,而且它是去中心化的。在TCC 或者 2PC 的方案中,必须具有事务协调器来处理每个不同服务之间的状态,而此种方案不需要事务协调器。 另外 2PC/TCC 这种方案如果服务依赖过多,会带来管理复杂性增加和稳定性风险增大的问题。试想如果我们强依赖 10 个服务,9 个都执行成功了,最后一个执行失败了,那么是不是前面 9 个都要回滚掉?这个成本还是非常高的。
但是,并不是说 2PC 或者 TCC 这种方案不好,因为每一种方案都有其相对优势的使用场景和优缺点。

幂等性

幂等性(你可以在Wikipedia读到关于幂等性的定义),当我们谈论幂等时,一般是指可以重复处理传递的消息,而不会产生意外的结果。

交付保证

在说幂等性之前,我们先来说下关于消费端的消息交付。
由于CAP不是使用的 MS DTC 或其他类型的2PC分布式事务机制,所以存在至少消息严格交付一次的问题,具体的说在基于消息的系统中,存在以下三种可能:

  • Exactly Once(*) (仅有一次)
  • At Most Once (最多一次)
  • At Least Once (最少一次)

    At Most Once

    最多一次交付保证,涵盖了保证一次或根本不接收所有消息的情况。
    这种类型的传递保证可能来自你的消息系统,你的代码按以下顺序执行其操作: ```csharp
  1. 从队列移除消息
  2. 开始一个工作事务
  3. 处理消息 ( 你的代码 )
  4. 是否成功 ? Yes:
    1. 1. 提交工作事务
    No:
    1. 1. 回滚工作事务
    2. 2. 将消息发回到队列。
    ``` 正常情况下,他们工作的很好,工作事务将被提交。
    然而,有些时候并不能总是成功,比如在 1 之后出现异常,或者是你在将消息放回到队列中出现网络问题由或者宕机重启等情况。
    使用这个协议,你将冒着丢失消息的风险,如果可以接受,那就没有关系。

    At Least Onc

    这个交付保证包含你收到至少一次的消息,当出现故障时,可能会收到多次消息。
    它需要稍微改变我们执行步骤的顺序,它要求消息队列系统支持事务或ACK机制,比如传统的 begin-commit-rollback 协议(MSMQ是这样),或者是 receive-ack-nack 协议(RabbitMQ,Azure Service Bus等是这样的)。
    大致步骤如下: ```csharp
  5. 抢占队列中的消息。
  6. 开始一个工作事务
  7. 处理消息 ( 你的代码 )
  8. 是否成功 ? Yes:
    1. 1. 提交工作事务
    2. 2. 从队列删除消息
    No:
    1. 1. 回滚工作事务
    2. 2. 从队列释放抢占的消息
    ``` 当出现失败或者抢占消息超时的时候,我们总是能够再次接收到消息以保证我们工作事务提交成功。

    什么是 “工作事务” ?

    上面所说的“工作事务”并不是特指关系型数据库中的事务,这里的工作事务是一个概念,也就是说执行代码的原子性。
    比如它可以是传统的RDMS事务,也或者是 MongoDB 事务或者是一个交易等。
    在这里它代表一个执行单元,这个执行单元是一个概念性的事实以支持前面提到的仅交付一次的这种问题。
    通常,不可能做到消息的事务和工作事务来形成原子性进行提交或者回滚。

    CAP 中的幂等性

    在CAP中,我们采用的交付保证为 At Least Once。
    由于我们具有临时存储介质(数据库表),也许可以做到 At Most Once, 但是为了严格保证消息不会丢失,CAP没有提供相关功能或配置。

    示例

    https://www.yuque.com/yuzhao/ltqbix/no04mi