Dtmcli 1.2.0

.NET 5.0 .NET Standard 2.0
Install-Package Dtmcli -Version 1.2.0
dotnet add package Dtmcli --version 1.2.0
<PackageReference Include="Dtmcli" Version="1.2.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Dtmcli --version 1.2.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Dtmcli, 1.2.0"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install Dtmcli as a Cake Addin
#addin nuget:?package=Dtmcli&version=1.2.0

// Install Dtmcli as a Cake Tool
#tool nuget:?package=Dtmcli&version=1.2.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

English | 简体中文

dtmcli-csharp

dtmcli-csharp is the C# client of Distributed Transaction Manager DTM that communicates with DTM Server through HTTP protocol.

It has supported distributed transaction patterns of Saga pattern, TCC pattern and 2-phase message pattern.

Build_And_Test codecov

What is DTM

DTM is a distributed transaction solution which provides cross-service eventually data consistency. It provides saga, tcc, xa, 2-phase message strategies for a variety of application scenarios. It also supports multiple languages and multiple store engine to form up a transaction as following:

<img alt="function-picture" src="https://en.dtm.pub/assets/function.7d5618f8.png" height=250 />

Features

  • Extremely easy to adapt

    • Support HTTP and gRPC, provide easy-to-use programming interfaces, lower substantially the barrier of getting started with distributed transactions. Newcomers can adapt quickly.
  • Easy to use

    • Relieving developers from worrying about suspension, null compensation, idempotent transaction, and other tricky problems, the framework layer handles them all.
  • Language-agnostic

    • Suit for companies with multiple-language stacks. Easy to write bindings for Go, Python, PHP, Node.js, Ruby, and other languages.
  • Easy to deploy, easy to extend

    • DTM depends only on MySQL, easy to deploy, cluster, and scale horizontally.
  • Support for multiple distributed transaction protocol

    • TCC, SAGA, XA, Transactional messages.

DTM vs. others

There is no mature open-source distributed transaction framework for non-Java languages. Mature open-source distributed transaction frameworks for Java language include Ali's Seata, Huawei's ServiceComb-Pack, Jingdong's shardingsphere, himly, tcc-transaction, ByteTCC, and so on, of which Seata is most widely used.

The following is a comparison of the main features of dtm and Seata.

Features DTM Seata Remarks
Supported languages <span style="color:green">Golang, C#, Java, Python, PHP, and others</span> <span style="color:orange">Java</span> dtm allows easy access from a new language
Exception handling Sub-transaction barrier <span style="color:orange">manual</span> dtm solves idempotent transaction, hanging, null compensation
TCC <span style="color:green">✓</span> <span style="color:green">✓</span>
XA <span style="color:green">✓</span> <span style="color:green">✓</span>
AT <span style="color:orange">suggest XA</span> <span style="color:green">✓</span> AT is similar to XA with better performance but with dirty rollback
SAGA <span style="color:green">support concurrency</span> <span style="color:green">complicated state-machine mode</span> dtm's state-machine mode is being planned
Transactional Messaging <span style="color:green">✓</span> <span style="color:red">✗</span> dtm provides Transactional Messaging similar to RocketMQ
Multiple DBs in a service <span style="color:green">✓</span> <span style="color:red">✗</span>
Communication protocols <span style="color:green">HTTP, gRPC</span> <span style="color:green">Dubbo, no HTTP</span>
Star count <img src="https://img.shields.io/github/stars/dtm-labs/dtm.svg?style=social" alt="github stars"/> <img src="https://img.shields.io/github/stars/seata/seata.svg?style=social" alt="github stars"/> dtm 0.1 is released from 20210604 and under fast development

From the features' comparison above, if your language stack includes languages other than Java, then dtm is the one for you. If your language stack is Java, you can also choose to access dtm and use sub-transaction barrier technology to simplify your business development.

Installation

Add nuget package via the following command

dotnet add package Dtmcli

Configuration

There are two ways to configure

  1. Configure with setup action
services.AddDtmcli(x =>
{
    // DTM server HTTP address
    x.DtmUrl = "http://localhost:36789";
    
    // request timeout for DTM server, unit is milliseconds
    x.DtmTimeout = 10000; 
    
    // request timeout for trans branch, unit is milliseconds
    x.BranchTimeout = 10000;
    
    // barrier database type, mysql, postgres, sqlserver
    x.DBType = "mysql";

    // barrier table name
    x.BarrierTableName = "dtm_barrier.barrier";
});
  1. Configure with IConfiguration
services.AddDtmcli(Configuration, "dtm");

And the configuration file

{
  "dtm": {
    "DtmUrl": "http://localhost:36789",
    "DtmTimeout": 10000,
    "BranchTimeout": 10000,
    "DBType": "mysql",
    "BarrierTableName": "dtm_barrier.barrier",
  }
}

Usage

SAGA pattern

public class MyBusi
{ 
    private readonly Dtmcli.IDtmTransFactory _transFactory;

    public MyBusi(Dtmcli.IDtmTransFactory transFactory)
    {
        this._transFactory = transFactory;
    }

    public async Task DoBusAsync()
    {
        var gid = Guid.NewGuid().ToString();
        var req = new BusiReq {  Amount = 30 };
        
        // NOTE: After DTM v1.12.2
        // when svc start with http or https, DTM server will send HTTP request to svc
        // when svc don't start with http or https,  DTM server will send gRPC request to svc
        var svc = "http://localhost:5005";

        var saga = _transFactory.NewSaga(gid);
        // Add sub-transaction
        saga.Add(
            // URL of forward action 
            svc + "/api/TransOut",
            
            // URL of compensating action
            svc + "/api/TransOutCompensate",

            // Arguments of actions
            req);
        saga.Add(
            svc + "/api/TransIn",
            svc + "/api/TransInCompensate",
            req);

        await saga.Submit();
    }
}

TCC pattern

public class MyBusi
{ 
    private readonly Dtmcli.TccGlobalTransaction _globalTransaction;

    public MyBusi(Dtmcli.TccGlobalTransaction globalTransaction)
    {
        this._globalTransaction = globalTransaction;
    }

    public async Task DoBusAsync()
    {
        var gid = Guid.NewGuid().ToString();
        var req = new BusiReq {  Amount = 30 };
        var svc = "http://localhost:5005";

        await _globalTransaction.Excecute(gid, async tcc =>
        {
            // Create tcc sub-transaction
            await tcc.CallBranch(
                // Arguments of stages
                req,

                // URL of Try stage
                svc + "/api/TransOutTry",

                // URL of Confirm stage
                svc + "/api/TransOutConfirm",

                 // URL of Cancel stage
                svc + "/api/TransOutCancel");

            await tcc.CallBranch(
                req,
                svc + "/api/TransInTry",
                svc + "/api/TransInConfirm",
                svc + "/api/TransInCancel");
        });
    }
}

2-phase message pattern

public class MyBusi
{ 
    private readonly Dtmcli.IDtmTransFactory _transFactory;

    public MyBusi(Dtmcli.IDtmTransFactory transFactory)
    {
        this._transFactory = transFactory;
    }

    public async Task DoBusAsync()
    {
        var gid = Guid.NewGuid().ToString();
        var req = new BusiReq {  Amount = 30 };
        var svc = "http://localhost:5005";

        var msg = _transFactory.NewMsg(gid);
        // Add sub-transaction
        msg.Add(
            // URL of action 
            svc + "/api/TransOut",

            // Arguments of action
            req);
        msg.Add(
            svc + "/api/TransIn",
            req);

        // Usage 1:
        // Send prepare message 
        await msg.Prepare(svc + "/api/QueryPrepared");
        // Send submit message
        await msg.Submit();

        // Usage 2:
        using (var conn = GetDbConnection())
        {
            await msg.DoAndSubmitDB(svc + "/api/QueryPrepared", conn, async tx => 
            {
                await conn.ExecuteAsync("insert ....", new { }, tx);
                await conn.ExecuteAsync("update ....", new { }, tx);
                await conn.ExecuteAsync("delete ....", new { }, tx);
            });
        }
    }
}

Complete example

Refer to https://github.com/dtm-labs/dtmcli-csharp-sample

Contact us

Wechat communication group

Add wechat friend with id yedf2008, or scan the OR code. Fill in csharp as verification.

yedf2008

Product Versions
.NET net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows
.NET Core netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1
.NET Standard netstandard2.0 netstandard2.1
.NET Framework net461 net462 net463 net47 net471 net472 net48
MonoAndroid monoandroid
MonoMac monomac
MonoTouch monotouch
Tizen tizen40 tizen60
Xamarin.iOS xamarinios
Xamarin.Mac xamarinmac
Xamarin.TVOS xamarintvos
Xamarin.WatchOS xamarinwatchos
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Dtmcli:

Package Downloads
Dtmcli.EFCore

对Dtmcli的二次封装

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.2.0 131 6/13/2022
1.2.0-alpha20220819004738 8 8/19/2022
1.2.0-alpha20220613151301 41 6/13/2022
1.1.2 352 5/26/2022
1.1.2-alpha20220526153318 48 5/26/2022
1.1.2-alpha20220519145309 49 5/19/2022
1.1.1 95 5/14/2022
1.1.1-alpha20220514032637 56 5/14/2022
1.1.0 144 4/9/2022
1.1.0-alpha20220409030258 53 4/9/2022
1.0.0 178 3/1/2022
1.0.0-alpha20220329140755 48 3/29/2022
1.0.0-alpha20220328161232 51 3/28/2022
1.0.0-alpha20220328161158 48 3/28/2022
1.0.0-alpha20220301143642 55 3/1/2022
1.0.0-alpha20220223043821 54 2/23/2022
1.0.0-alpha20220221134440 53 2/21/2022
0.5.0 89 2/19/2022
0.5.0-alpha20220219075114 55 2/19/2022
0.5.0-alpha20220218100129 56 2/18/2022
0.5.0-alpha20220216140508 58 2/16/2022
0.5.0-alpha20220213045321 58 2/13/2022
0.5.0-alpha20220213035502 57 2/13/2022
0.5.0-alpha20220213014814 57 2/13/2022
0.5.0-alpha20220210044934 54 2/10/2022
0.4.0 123 2/5/2022
0.4.0-alpha20220209092027 55 2/9/2022
0.4.0-alpha20220205130133 62 2/5/2022
0.4.0-alpha20220205025645 62 2/5/2022
0.4.0-alpha20220203054543 70 2/3/2022
0.4.0-alpha20220203035129 71 2/3/2022
0.4.0-alpha20220131041847 77 1/31/2022
0.4.0-alpha20220128011854 67 1/28/2022
0.4.0-alpha20220125123820 70 1/25/2022
0.3.0 167 1/21/2022
0.3.0-alpha20220125123431 66 1/25/2022
0.3.0-alpha20220121003512 59 1/21/2022
0.3.0-alpha20220120125355 73 1/20/2022
0.3.0-alpha20220120061225 68 1/20/2022
0.3.0-alpha20220119151323 88 1/19/2022
0.3.0-alpha20220119121047 67 1/19/2022
0.3.0-alpha20220119102945 67 1/19/2022
0.2.0.1910 201 8/1/2021
0.2.0-preview 152 8/1/2021
0.1.0-preview 152 7/30/2021