dtm is a free, open source orchestration & scheduling project written in Go and released under BSD-3-Clause. It has 10,918 GitHub stars, 997 forks and 87 open issues, and was last pushed 9 months ago. On this registry it ranks #18 of 64 tracked projects in Orchestration & Scheduling, with 5 head-to-head comparisons available.

What is dtm?

DTM is a distributed transaction framework that provides cross-service eventual data consistency for microservices, with saga, TCC, XA, 2-phase message, outbox, and workflow patterns plus SDKs for Go, Java, PHP, C#, Python, and Node.js.

What it is

DTM — Distributed Transactions Manager — is an open-source framework written in Go and released under the BSD-3-Clause licence, listed in this registry under Infrastructure & Operations / Orchestration & Scheduling. It coordinates a single logical transaction across branches that run in separate microservices, giving a transaction manager that drives each branch forward and, when something fails, invokes the compensation the branch declared. It supports a range of transaction modes (SAGA, TCC, XA, Workflow, Outbox, 2-phase message), multiple languages, and multiple storage engines, so a transaction can span several services and several kinds of datastore.

The concrete problem it solves is the bookkeeping of partial failure. When one service in a chain commits and a downstream service does not, the application is left to invent compensation logic, retries, and consistency checks by hand, or to push that work into asynchronous messaging. DTM takes that job: branches register their own rollback behaviour, and the framework sequences commit and compensation according to the chosen pattern. It lives in the Go microservice ecosystem, with direct integration for go-zero, go-kratos/kratos, and polarismesh/polaris, and for message-driven flows it offers 2-phase messages as a more elegant replacement for plain Outbox implementations.

Key capabilities

  • Multiple transaction modes in one framework: SAGA, TCC, XA, Workflow, Outbox, and 2-phase message.
  • Language SDKs for Go, Java, PHP, C#, Python, and Nodejs, so services written in different stacks can join the same transaction.
  • Multi-database transaction support across MySQL/MariaDB, Redis, MongoDB, Postgres, and TDSQL.
  • Pluggable storage engines for the transaction state itself: MySQL/MariaDB as the common choice, Redis for high performance, and BoltDB for development and testing, with MongoDB under planning.
  • Better Outbox through 2-phase messages, supporting multiple databases rather than a single one.
  • Workflow orchestration API with workflow.Register, workflow.ExecuteCtx, and branches built as wf.NewBranch().OnRollback(...).
  • High availability and easy horizontal scaling of the transaction manager itself.

Who uses it and how

  • Large platform operators run it in production; the project's partial user list names Tencent, Bytedance, and Ivydad.
  • Teams managing caches use it to guarantee cache final consistency and strong consistency between cache and database.
  • Flash-sale systems use it to deduct inventory so that, in extreme cases, the precise inventory held in Redis matches the final order created, without manual adjustment.
  • Non-monolithic order systems use it to coordinate order services spread across microservices, which the project describes as dramatically simplifying the architecture.
  • Event publishing and subscription flows use the outbox pattern built on 2-phase messages for reliable delivery.

Getting started

Clone the repository and run the manager directly from source with git clone https://github.com/dtm-labs/dtm && cd dtm followed by go run main.go. A runnable example, the inter-bank transfer sample with separate TransOut and TransIn microservices, is available via git clone https://github.com/dtm-labs/quick-start-sample.git && cd quick-start-sample/workflow-grpc and go run main.go.

How it compares

The facts supplied here do not list paid products that DTM replaces, so no licence, hosting, or cost-model contrast can be drawn against named commercial alternatives. Within the ecosystem it does name, DTM positions itself alongside the Go microservice frameworks go-zero, go-kratos/kratos, and polarismesh/polaris, which it integrates with rather than competes against, and its topic list groups it with workflow orchestration work in the style of Cadence.

When to use it — and when not to

A self-hoster must run the transaction manager and a store engine behind it, choosing between MySQL/MariaDB, Redis, or BoltDB, and must accept that MongoDB support is still under planning, so MongoDB-backed deployments are not yet a first-class option. The project documentation is a cookbook and quick-start collection on its homepage rather than a managed service, meaning there is no hosted option indicated here and the operational work — running, scaling, and keeping the transaction store available — stays with the adopting team. Teams that want a fully managed distributed-transaction service, or that cannot operate a database alongside the framework, should look elsewhere; teams with Go or multi-language microservices that need saga, TCC, or 2-phase message coordination are the intended fit.

project readme (upstream, from github) — read inline

license Build Status codecov Go Report Card Go Reference Mentioned in Awesome Go

English | 简体中文

Distributed Transactions Manager

What is DTM

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

function-picture

Who's using DTM (partial)

Tencent

Bytedance

Ivydad

More

Features

  • Support for multiple transaction modes: SAGA, TCC, XA, Workflow, Outbox
  • Multiple languages support: SDK for Go, Java, PHP, C#, Python, Nodejs
  • Better Outbox: 2-phase messages, a more elegant solution than Outbox, support multi-databases
  • Multiple database transaction support: MySQL/MariaDB, Redis, MongoDB, Postgres, TDSQL, etc.
  • Support for multiple storage engines: MySQL/MariaDB (common), Redis (high performance), BoltDB (dev&test), MongoDB (under planning)
  • Support for multiple microservices architectures: go-zero, go-kratos/kratos, polarismesh/polaris
  • Support for high availability and easy horizontal scaling

Application scenarios.

DTM can be applied to data consistency issues in a large number of scenarios, here are a few common ones

Cook Book

Quick start

run dtm

git clone https://github.com/dtm-labs/dtm && cd dtm
go run main.go

Start an example

Suppose we want to perform an inter-bank transfer. The operations of transfer out (TransOut) and transfer in (TransIn) are coded in separate micro-services.

Here is an example to illustrate a solution of dtm to this problem:

git clone https://github.com/dtm-labs/quick-start-sample.git && cd quick-start-sample/workflow-grpc
go run main.go

Code

Usage

wfName := "workflow-grpc"
err = workflow.Register(wfName, func(wf *workflow.Workflow, data []byte) error {
  // ...
  // Define a transaction branch for TransOut
  wf.NewBranch().OnRollback(func(bb *dtmcli.BranchBarrier) error {
    // compensation for TransOut
    _, err := busiCli.TransOutRevert(wf.Context, &req)
    return err
  })
  _, err = busiCli.TransOut(wf.Context, &req)
  // check error

  // Define another transaction branch for TransIn
  wf.NewBranch().OnRollback(func(bb *dtmcli.BranchBarrier) error {
    _, err := busiCli.TransInRevert(wf.Context, &req)
    return err
  })
  _, err = busiCli.TransIn(wf.Context, &req)
  return err
}

// ...
req := busi.BusiReq{Amount: 30, TransInResult: ""}
data, err := proto.Marshal(&req)

// Execute workflow
_, err = workflow.ExecuteCtx(wfName, shortuuid.New(), data)
logger.Infof("result of workflow.Execute is: %v", err)

When the above code runs, we can see in the console that services TransOut, TransIn has been called.

Rollback upon failure

If any forward operation fails, DTM invokes the corresponding compensating operation of each sub-transaction to roll back, after which the transaction is successfully rolled back.

Let's purposely trigger the failure of the second sub-transaction and watch what happens

// req := busi.BusiReq{Amount: 30, TransInResult: ""}
req := busi.BusiReq{Amount: 30, TransInResult: "FAILURE"}
})

we can see in the console that services TransOut, TransIn, TransOutRevert has been called

More examples

If you want more quick start examples, please refer to dtm-labs/quick-start-sample

The above example mainly demonstrates the flow of a distributed transaction. More on this, including practical examples of how to interact with an actual database, how to do compensation, how to do rollback, etc. please refer to dtm-examples for more examples.

Give a star! ⭐

If you think this project is interesting, or helpful to you, please give a star!

Frequently asked questions

Is dtm free to use?

dtm is open source under the BSD-3-Clause licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does dtm do?

A distributed transaction framework, supports workflow, saga, tcc, xa, 2-phase message, outbox patterns, supports many languages.

What is dtm written in?

dtm is primarily written in Go. Its source is publicly available at https://github.com/dtm-labs/dtm, and it has 10,918 GitHub stars.