Mastering Distributed Transactions: CAP, BASE, 2PC, TCC, Sagas and .NET CAP
This article explains the fundamentals of distributed transactions, covering ACID and CAP theory, the BASE model, and compares common solutions such as two‑phase commit, TCC, local message tables, MQ transactional messages, and Sagas, while also introducing the open‑source .NET CAP framework with its features and limitations.
Introduction
Distributed transactions become necessary when a single database cannot satisfy performance or scalability requirements and data is partitioned across multiple nodes. In such environments the classic ACID guarantees are hard to maintain.
Database Transaction Basics
Traditional transactions provide the ACID properties: Atomicity , Consistency , Isolation , and Durability . Most relational engines write changes to a redo log before modifying the data pages; on restart the engine can undo or redo operations to recover a consistent state after a crash.
CAP Theorem
The CAP theorem states that a distributed system can provide at most two of the following three guarantees:
Consistency – all nodes see the same data at the same time.
Availability – every request receives a response.
Partition tolerance – the system continues operating despite network partitions.
Designers must trade off consistency for availability when scaling horizontally.
BASE Theory
BASE (Basically Available, Soft state, Eventual consistency) relaxes strict consistency in favor of higher availability. Systems aim for eventual consistency rather than the strong guarantees of ACID.
Distributed Transaction Solutions
1. Two‑Phase Commit (2PC)
2PC implements the XA protocol. The coordinator first asks all participants to pre‑commit (phase 1). If every participant votes to commit, the coordinator issues a commit (phase 2); otherwise it aborts. This yields strong consistency but adds latency, complexity, and reduces fault tolerance. XA support is available in MySQL 5.5+, SQL Server 2005+, Oracle 7+.
2. TCC (Try‑Confirm‑Cancel)
TCC splits a business operation into three explicit steps:
Try : reserve resources and perform validation.
Confirm : finalize the operation once the Try succeeds.
Cancel : roll back the reservation if any later step fails.
Example: a money‑transfer service freezes funds in the Try step, commits the transfer in Confirm, and releases the freeze in Cancel when an error occurs.
3. Local Message Table (Asynchronous Assurance)
Each service writes business data and a corresponding message record inside the same local transaction. A background worker reads pending messages and publishes them to a message queue. If publishing fails, the message is retried. This pattern achieves eventual consistency without distributed locks.
4. MQ Transactional Messages
Some message queues (e.g., RocketMQ) provide transactional messages that mimic 2PC:
Prepare a message and store it locally.
Execute the local transaction.
Commit or roll back the prepared message based on the transaction outcome.
RocketMQ requires a check interface for uncertain states. Most mainstream MQs such as RabbitMQ and Kafka lack native transaction support, and .NET clients for RocketMQ are not available.
5. Saga Model
Sagas decompose a long‑running transaction into a series of local transactions coordinated by a workflow engine. If any step fails, compensating actions are executed in reverse order.
SagaBuilder saga = SagaBuilder.newSaga("trip")
.activity("Reserve car", ReserveCarAdapter.class)
.compensationActivity("Cancel car", CancelCarAdapter.class)
.activity("Book hotel", BookHotelAdapter.class)
.compensationActivity("Cancel hotel", CancelHotelAdapter.class)
.activity("Book flight", BookFlightAdapter.class)
.compensationActivity("Cancel flight", CancelFlightAdapter.class)
.end()
.triggerCompensationOnAnyError();
camunda.getRepositoryService()
.createDeployment()
.addModelInstance(saga.getModel())
.deploy();The Saga approach provides eventual consistency with explicit compensation but requires a workflow engine; .NET implementations are still emerging.
.NET CAP Open‑Source Framework
CAP (not the CAP theorem) is an open‑source .NET library that implements distributed‑transaction patterns using message queues and relational databases. Core capabilities include:
Support for RabbitMQ, Kafka, SQL Server, MySQL, PostgreSQL.
Extensible interfaces for serialization, custom processing, and routing.
Integration points for service discovery and health checks (e.g., Consul).
CAP enables eventual consistency while offering patterns similar to 2PC, TCC, local‑message tables, and Sagas.
References
GitHub repository: https://github.com/dotnetcore/CAP
Additional reading: http://www.cnblogs.com/savorboard/p/cap.html (introduction) and http://www.cnblogs.com/savorboard/p/cap-document.html (documentation)
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architects' Tech Alliance
Sharing project experiences, insights into cutting-edge architectures, focusing on cloud computing, microservices, big data, hyper-convergence, storage, data protection, artificial intelligence, industry practices and solutions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
