Sample application of Spring Data JDBC for ScalarDB with Microservice Transactions
This tutorial describes how to create a sample Spring Boot application for microservice transactions by using Spring Data JDBC for ScalarDB.
For details about these features, see Two-phase Commit Transactions and Guide of Spring Data JDBC for ScalarDB.
Prerequisites
- Java (OpenJDK 8 or higher)
- Gradle
- Docker, Docker Compose
In addition, you need access to the ScalarDB SQL GitHub repository and Packages in ScalarDB SQL repository. These repositories are available only to users with a commercial license and permission. To get a license and permission, please contact us.
You also need the gpr.user property for your GitHub username and the gpr.key property for your personal access token.
You must either add these properties in ~/.gradle/gradle.properties or specify the properties by using the -P option when running the ./gradlew command as follows:
$ ./gradlew run ... -Pgpr.user=<YOUR_GITHUB_USERNAME> -Pgpr.key=<YOUR_PERSONAL_ACCESS_TOKEN>
Or you can also use environment variables, USERNAME for your GitHub username and TOKEN for your personal access token.
$ export USERNAME=<YOUR_GITHUB_USERNAME>
$ export TOKEN=<YOUR_PERSONAL_ACCESS_TOKEN>
For more details, see Install - ScalarDB SQL.
Sample application
Overview
This tutorial describes how to create a Spring Boot sample application for microservice transactions for the same use case as ScalarDB Sample but by using Two-phase Commit Transactions in ScalarDB.
There are two microservices called the Customer Service and the Order Service based on the Database-per-service pattern in this sample application.
The Customer Service manages customers' information including credit card information like a credit limit and a credit total. The Order Service is responsible for order operations like placing an order and getting order histories. Each service has gRPC endpoints. Clients call the endpoints, and the services call the endpoints each other as well. The Customer Service and the Order Service use MySQL and Cassandra through ScalarDB, respectively.

Note that both services access a small coordinator database used for the Consensus Commit protocol. The coordinator database is service-independent and exists for managing transaction metadata for Consensus Commit in a highly available manner. We believe the architecture does not spoil the benefits of the database-per-service pattern. NOTE: We also plan to create a microservice container for the coordinator database to truly achieve the database-per-service pattern.
In this sample application, for ease of setup and explanation, we co-locate the coordinator database in the same Cassandra instance of the Order Service, but of course, the coordinator database can be managed as a separate database.
Also, note that application-specific error handling, authentication processing, etc., are omitted in the sample application since it focuses on explaining how to use ScalarDB. Please see this document for the details of how to handle exceptions in ScalarDB.
Additionally, you assume each service has one container in this sample application to avoid considering request routing between the services. However, for production, because each service typically has multiple servers (or hosts) for scalability and availability, please consider to use ScalarDB Cluster which easily addresses request routing between the services in Two-phase Commit Transactions. Please see this document for the details of Request Routing in Two-phase Commit Transactions.
Schema
The schema is as follows:
CREATE COORDINATOR TABLES IF NOT EXIST;
CREATE NAMESPACE IF NOT EXISTS customer_service;
CREATE TABLE IF NOT EXISTS customer_service.customers (
customer_id INT PRIMARY KEY,
name TEXT,
credit_limit INT,
credit_total INT
);
CREATE NAMESPACE IF NOT EXISTS order_service;
CREATE TABLE IF NOT EXISTS order_service.orders (
customer_id INT,
timestamp BIGINT,
order_id TEXT,
PRIMARY KEY (customer_id, timestamp)
);
CREATE INDEX IF NOT EXISTS ON order_service.orders (order_id);
CREATE TABLE IF NOT EXISTS order_service.statements (
order_id TEXT,
item_id INT,
count INT,
PRIMARY KEY (order_id, item_id)
);
CREATE TABLE IF NOT EXISTS order_service.items (
item_id INT PRIMARY KEY,
name TEXT,
price INT
);
All the tables are created in the customer_service and order_service namespaces.
customer_service.customers: a table that manages customers' informationcredit_limit: the maximum amount of money a lender will allow each customer to spend when using a credit cardcredit_total: the amount of money that each customer has already spent by using the credit card
order_service.orders: a table that manages order informationorder_service.statements: a table that manages order statement informationorder_service.items: a table that manages information of items to be ordered
The Entity Relationship Diagram for the schema is as follows:
