Managing Distributed Transactions in Spring Cloud Using Seata

Deploy Seata 2.0.0 alongside Nacos 1.4.1 in standalone mode. Begin by initializing the Seata configuration database and importing registry settings into Nacos via sh nacos-config.sh from the source root. After import, verify configurasions appear in the Nacos console.

Configure Seata's application.yml to use Nacos for both configuration and service registration:

 server:
   port: 7091

spring:
  application:
    name: seata-server

logging:
  config: classpath:logback-spring.xml
  file:
    path: ${log.home:${user.home}/logs/seata}

console:
  user:
    username: seata
    password: seata

seata:
  config:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      data-id: seataServer.properties
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      cluster: default
  security:
    secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
    tokenValidityInMilliseconds: 1800000
    ignore:
      urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.jpeg,/**/*.ico,/api/v1/auth/login,/metadata/v1/**

Start the Seata server; it should register successfully with Nacos.

Create three Spring Boot microservices within a Maven parenet project: user-svc, order-svc, and inventory-svc. Use Feign for inter-service calls. Resolve dependency conflicts by aligning Spring Boot and Spring Cloud versions and applying exclusions via the Maven Dependency Analyzer.

Prepare three databases with these schemas:

user_account.sql

DROP TABLE IF EXISTS user_account;
CREATE TABLE user_account (
  uid INT AUTO_INCREMENT PRIMARY KEY,
  customer_ref VARCHAR(255),
  balance INT DEFAULT 0
);
INSERT INTO user_account VALUES (11111111, '2', 1000);

customer_order.sql

DROP TABLE IF EXISTS customer_order;
CREATE TABLE customer_order (
  oid INT AUTO_INCREMENT PRIMARY KEY,
  customer_ref VARCHAR(1000),
  product_code VARCHAR(255),
  quantity INT DEFAULT 0,
  total_price INT DEFAULT 0
);

product_stock.sql

DROP TABLE IF EXISTS product_stock;
CREATE TABLE product_stock (
  sid INT AUTO_INCREMENT PRIMARY KEY,
  product_code VARCHAR(255),
  stock_count INT DEFAULT 0,
  created_at DATETIME,
  updated_at DATETIME
);
INSERT INTO product_stock VALUES (1, 'iphone11', 100, '2020-09-28 16:55:51', '2020-10-14 16:13:21');

Implement service logic:

  • user-svc records an order and decrements the customer's balance.
  • order-svc logs the order and reduces product inventory.
  • inventory-svc adjusts stock according to ordered quantity.

Without Seata integration, bussiness flow executes normally but lacks atomicity. With Seata's global transaction handling enabled—typically via @GlobalTransactional annotation—consistency across services is enforced.

Launch all services and invoke http://localhost:10000/userAccount/createOrder. On success, logs confirm completion and database state matches expectations.

To test rollback, stop inventory-svc and introduce an artificial fault such as division by zero in order-svc. Trigger the endpoint again. Seata intercepts the failure, rolls back changes across all participants, and leaves databases unmodified.

Ensure the transaction group name used in clients matches the value defined in Seata's config.txt registered in Nacos (commonly default_tx_group). Connection errors often stem from mismatched network settings or incorrect group configuration.

Tags: Spring Cloud Seata Distributed Transaction Nacos microservices

Posted on Sun, 06 Sep 2026 16:10:48 +0000 by guanche