.NET开源的处理分布式事务的解决方案

前言

在分布式系统中,由于各个系统服务之间的独立性和网络通信的不确定性,要确保跨系统的事务操作的最终一致性是一项重大的挑战。今天给大家推荐一个.NET开源的处理分布式事务的解决方案基于 .NET Standard 的 C# 库:CAP。

CAP项目介绍

CAP 是一个基于 .NET Standard 的 C# 库,它是一种处理分布式事务的解决方案,同样具有 EventBus 的功能,它具有轻量级、易使用、高性能等特点。CAP 是一个EventBus,同时也是一个在微服务或者SOA系统中解决分布式事务问题的一个框架。它有助于创建可扩展,可靠并且易于更改的微服务系统。

什么是 EventBus?

事件总线是一种机制,它允许不同的组件彼此通信而不彼此了解。组件可以将事件发送到Eventbus,而无需知道是谁来接听或有多少其他人来接听。组件也可以侦听Eventbus上的事件,而无需知道谁发送了事件。这样,组件可以相互通信而无需相互依赖。同样,很容易替换一个组件。只要新组件了解正在发送和接收的事件,其他组件就永远不会知道。

CAP架构预览

CAP支持的存储

SQL Server、MySQL、PostgreSql、MongoDB、In-Memory Storage。

CAP 支持以下几种运输方式

RabbitMQ、Kafka、Azure Service Bus、Amazon SQS、NATS、In-Memory Queue、Redis Streams、Apache Pulsar。

怎么选择运输器

项目源码

快速开始

安装DotNetCore.CAP Nuget包

CAP 支持主流的消息队列作为传输器:

  • 我本地安装的是DotNetCore.CAP.RabbitMQ。

    //你可以按需选择下面的包进行安装:
    PM> Install-Package DotNetCore.CAP.Kafka
    PM> Install-Package DotNetCore.CAP.RabbitMQ
    PM> Install-Package DotNetCore.CAP.AzureServiceBus
    PM> Install-Package DotNetCore.CAP.AmazonSQS
    PM> Install-Package DotNetCore.CAP.NATS
    PM> Install-Package DotNetCore.CAP.RedisStreams
    PM> Install-Package DotNetCore.CAP.Pulsar

CAP 提供了主流数据库作为存储:

  • 我本地安装的是DotNetCore.CAP.MongoDB。

    // 按需选择安装你正在使用的数据库:
    PM> Install-Package DotNetCore.CAP.SqlServer
    PM> Install-Package DotNetCore.CAP.MySql
    PM> Install-Package DotNetCore.CAP.PostgreSql
    PM> Install-Package DotNetCore.CAP.MongoDB

配置CAP到 Program.cs 文件中,如下:

复制代码
            builder.Services.AddCap(x =>
            {
                //如果你使用的 EF 进行数据操作,你需要添加如下配置:
                //配置数据库上下文
                x.UseEntityFramework<AppDbContext>();

                //如果你使用的 MongoDB,你可以添加如下配置:
                x.UseMongoDB("ConnectionStrings");  //注意,仅支持MongoDB 4.0+集群

                //CAP RabbitMQ 配置
                x.UseRabbitMQ(rab => {
                    rab.HostName = "192.0.1.1";
                    rab.Password = "123456";
                    rab.Port = 5672;
                    rab.UserName = "123456";
                });
            });

发布

在 Controller 中注入 ICapPublisher 然后使用 ICapPublisher 进行消息发送。

复制代码
public class PublishController : Controller
{
    private readonly ICapPublisher _capBus;

    public PublishController(ICapPublisher capPublisher)
    {
        _capBus = capPublisher;
    }
    
    //不使用事务
    [Route("~/without/transaction")]
    public IActionResult WithoutTransaction()
    {
        _capBus.Publish("xxx.services.show.time", DateTime.Now);

        // Publish delay message
        _capBus.PublishDelayAsync(TimeSpan.FromSeconds(delaySeconds), "xxx.services.show.time", DateTime.Now);
 
        return Ok();
    }

    //Ado.Net 中使用事务,自动提交
    [Route("~/adonet/transaction")]
    public IActionResult AdonetWithTransaction()
    {
        using (var connection = new MySqlConnection(ConnectionString))
        {
            using (var transaction = connection.BeginTransaction(_capBus, autoCommit: true))
            {
                //业务代码

                _capBus.Publish("xxx.services.show.time", DateTime.Now);
            }
        }
        return Ok();
    }

    //EntityFramework 中使用事务,自动提交
    [Route("~/ef/transaction")]
    public IActionResult EntityFrameworkWithTransaction([FromServices]AppDbContext dbContext)
    {
        using (var trans = dbContext.Database.BeginTransaction(_capBus, autoCommit: true))
        {
            //业务代码

            _capBus.Publish("xxx.services.show.time", DateTime.Now);
        }
        return Ok();
    }
}

订阅

Action Method

在 Action 上添加 CapSubscribeAttribute 来订阅相关消息。

复制代码
public class PublishController : Controller
{
    [CapSubscribe("xxx.services.show.time")]
    public void CheckReceivedMessage(DateTime datetime)
    {
        Console.WriteLine(datetime);
    }
}
Service Method

如果你的订阅方法没有位于 Controller 中,则你订阅的类需要继承 ICapSubscribe:

复制代码
namespace xxx.Service
{
    public interface ISubscriberService
    {
        void CheckReceivedMessage(DateTime datetime);
    }

    public class SubscriberService: ISubscriberService, ICapSubscribe
    {
        [CapSubscribe("xxx.services.show.time")]
        public void CheckReceivedMessage(DateTime datetime)
        {
        }
    }
}

项目源码地址

更多项目实用功能和特性欢迎前往项目开源地址查看👀,别忘了给项目一个Star支持💖。

GitHub开源地址:https://github.com/dotnetcore/CAP

官方文档:https://cap.dotnetcore.xyz/

优秀项目和框架精选

该项目已收录到C#/.NET/.NET Core优秀项目和框架精选中,关注优秀项目和框架精选能让你及时了解C#、.NET和.NET Core领域的最新动态和最佳实践,提高开发工作效率和质量。坑已挖,欢迎大家踊跃提交PR推荐或自荐(让优秀的项目和框架不被埋没🤞)。

https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md

相关推荐
weixin_307779135 分钟前
C#实现两个DocumentDB实例之间同步数据
开发语言·数据库·c#·云计算
foundbug99912 分钟前
基于C#的OPC DA客户端实现源码解析
开发语言·c#
火山引擎开发者社区15 分钟前
火山引擎记忆库Mem0发布,全面兼容Mem0开源社区生态
开源·火山引擎
进击monkey21 分钟前
PandaWiki:开源企业级AI知识库工具,基于RAG架构的私有化部署方案
人工智能·开源
麦兜*32 分钟前
深入解析现代分布式事务架构:基于Seata Saga模式与TCC模式实现金融级高可用与数据最终一致性的工程实践全解析
分布式·金融·架构
开源能源管理系统37 分钟前
MyEMS开源能源管理系统在零碳工厂中的应用
开源·能源·能源管理系统
難釋懷1 小时前
分布式锁-redission功能介绍
分布式
Crazy Struggle2 小时前
.NET 中如何快速实现 List 集合去重?
c#·.net
ApacheSeaTunnel2 小时前
Apache SeaTunnel Zeta、Flink、Spark 怎么选?底层原理 + 实战对比一次讲透
大数据·flink·spark·开源·数据集成·seatunnel·数据同步
xb11323 小时前
C#生产者-消费者模式
开发语言·c#