Getting Started with Distributed Transactions with a Two-Phase Commit Interface in the ScalarDB Cluster .NET Client SDK
The ScalarDB Cluster .NET Client SDK supports transactions with the two-phase commit interface in ScalarDB. The SDK includes transaction and manager abstractions for enhanced communication within a cluster.
Although we recommend using asynchronous methods as in the following examples, you can use synchronous methods instead.
About transactions with the two-phase commit interface
By using the SDK, you can execute transactions with the two-phase commit interface that span multiple applications. For example, if you have multiple microservices, you can create a transaction manager in each of them and execute a transaction that spans those microservices.
In transactions with the two-phase commit interface, there are two roles—coordinator and a participant—that collaboratively execute a single transaction.
The coordinator process first begins a transaction and sends the ID of the transaction to all the participants, and the participant processes join the transaction. After executing CRUD or SQL operations, the coordinator process and the participant processes commit the transaction by using the two-phase interface.
Install the SDK
Install the same major and minor version of the SDK as ScalarDB Cluster into the .NET project. You can do this by using the built-in NuGet package manager, replacing <MAJOR>.<MINOR>
with the version that you're using:
dotnet add package ScalarDB.Net.Client --version '<MAJOR>.<MINOR>.*'
Get a transaction manager (for coordinator and participants)
First, you need to get a transaction manager for distributed transactions with the two-phase commit interface. To get the transaction manager, you can use TransactionFactory
as follows, replacing <HOSTNAME_OR_IP_ADDRESS>
with the FQDN or the IP address, and <PORT>
with the port number (60053
by default) of your cluster:
var scalarDbOptions = new ScalarDbOptions
{
Address = "http://<HOSTNAME_OR_IP_ADDRESS>:<PORT>",
HopLimit = 10
};
var factory = TransactionFactory.Create(scalarDbOptions);
using var manager = factory.GetTwoPhaseCommitTransactionManager();
Alternatively, you can use SQL instead of CRUD operations for transactions with the two-phase commit interface by specifying the following transaction manager:
using var manager = factory.GetSqlTwoPhaseCommitTransactionManager();
Begin a transaction (for coordinator)
You can begin a transaction with the two-phase commit interface in the coordinator as follows:
var transaction = await manager.BeginAsync();
The ID of the started transaction can be obtained with the following code:
var transactionId = transaction.Id;
Join a transaction (for participants)
You can join a transaction with the two-phase commit interface in a participant as follows:
var transaction = await manager.JoinAsync(transactionId);
Resume a transaction (for coordinator and participants)
Usually, a transaction with the two-phase commit interface involves multiple request and response exchanges. In scenarios where you need to work with a transaction that has been begun or joined in the previous request, you can resume such transaction as follows:
var transaction = manager.Resume(transactionId);
The Resume
method doesn't have an asynchronous version because it only creates a transaction object. Because of this, resuming a transaction by using the wrong ID is possible.
Roll back a transaction
If a transaction fails to commit, you can roll back the transaction as follows:
await transaction.RollbackAsync();
Commit a transaction (for coordinator and participants)
After completing CRUD or SQL operations, you must commit the transaction. However, for transactions with the two-phase commit interface, you must prepare the transaction in the coordinator and all the participants first.
await transaction.PrepareAsync();
Next, depending on the concurrency control protocol, you may need to validate the transaction in the coordinator and all the participants as follows:
await transaction.ValidateAsync();
Finally, you can commit the transaction in the coordinator and all the participants as follows:
await transaction.CommitAsync();
If the coordinator or any of the participants failed to prepare or validate the transaction, you will need to call RollbackAsync
in the coordinator and all the participants.
In addition, if the coordinator and all the participants failed to commit the transaction, you will need to call RollbackAsync
in the coordinator and all the participants.
However, if the coordinator or only some of the participants failed to commit the transaction, the transaction will be regarded as committed as long as the coordinator or any one of the participants has succeeded in committing the transaction.
Execute CRUD operations
The two-phase commit interface of the transaction has the same methods for CRUD operations as ordinary transactions. For details, see Execute CRUD operations.
Execute SQL statements
The two-phase commit interface of the SQL transaction has the same methods for executing SQL queries as ordinary SQL transactions. For details, see Execute SQL queries.