The services in this project are designed with microservice architecture for performing distributed transaction using 2-Phase Commit (2PC).
Each microservice exposes REST API interfaces that can be accessed through OpenAPI endpoint (/swagger-ui.html)
- SpringBoot
- Spring Data JPA
- MySQL Database
- RabbitMQ
-
RabbitMQ
- Start RabbitMQ in Docker with command
docker run -d --hostname my-rabbit --name some-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3-management
Learn more - RabbitMQ 管理控制台UI: http://localhost:15672 guest/guest
- Start RabbitMQ in Docker with command
-
MySQL Database
- Start MySQL in Docker with command
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
Learn more - init data:
create database distibuted_txn; create table accounts (id bigint not null primary key auto_increment, balance integer, customer_id bigint) engine =INNODB; create table orders (id bigint not null primary key auto_increment, customer_id bigint, product_id bigint, quantity integer) engine =INNODB ; create table products (id bigint not null primary key auto_increment, name varchar(255), price integer, quantity integer) engine =INNODB; insert into accounts values (1, 9999, 1); insert into products values (89, 'a test product', 3.2, 1000);
- Start MySQL in Docker with command
- Start
discovery-server
. Default port is 8761. - Start all microservices:
transaction-server
,account-service
,order-service
,product-service
- Add some test data to
account-service
andproduct-service
- Send order creation request to
order-service
for testing the flow. - 发起一个创建订单请求:
curl 'http://localhost:8081/orders' \ -H 'Accept: */*' \ -H 'Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7' \ -H 'Cache-Control: no-cache' \ -H 'Connection: keep-alive' \ -H 'Cookie: Idea-d73977e5=c55edb0c-bdc9-4d6f-a391-1ee92fd8b993; grafana_session=b2f237e09dc9674aa3e50d501d0a4f7a; grafana_session_expiry=1701593979; pma_lang=en; pmaUser-1=%7B%22iv%22%3A%22KXbaGSUUISqVWJhbPAEiiw%3D%3D%22%2C%22mac%22%3A%223083c06f225db464a4976e5543c2c60d960c400b%22%2C%22payload%22%3A%22YAegT9i4Bc02Kp7eEF%5C%2Fg1w%3D%3D%22%7D; m=59b9:true' \ -H 'Pragma: no-cache' \ -H 'Sec-Fetch-Dest: empty' \ -H 'Sec-Fetch-Mode: cors' \ -H 'Sec-Fetch-Site: none' \ -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' \ -H '___internal-request-id: a40f8884-18b0-48f5-ad52-033c6ab42014' \ -H 'content-type: application/json' \ -H 'sec-ch-ua: "Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"' \ -H 'sec-ch-ua-mobile: ?0' \ -H 'sec-ch-ua-platform: "macOS"' \ --data-raw $'{\n "productId":89,\n "quantity": 1,\n "customerId": 1\n}' \ --compressed
In this microservice-based architecture design, discovery-server
plays an important role for registering and retrieving the service instances from a centralize location.
The transaction-server
is responsible for maintaining transaction status for multiple services for a given transactionId.
There are three applications: order-service
, account-service
and product-service
.
The application order-service
is communicating with account-service
and product-service
. All these applications are using MySQL database as a backend store.