docker-compose.yaml:
version: "3" services: seata-server: image: seataio/seata-server hostname: seata-server ports: - "8091:8091" environment: - SEATA_PORT=8091 - STORE_MODE=file MySQL docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:latest 目录结构Storage : 商品库存逻辑模块;
Account: 用户账户逻辑模块;
Order: 商品订单逻辑模块;
Business: 业务层逻辑模块;
下面我通过Storage模块来描述Dubbo + Seata的接入,其他模块,例如account, order模块的接入都是相同的。
Storage商品库存模块 项目目录 . ├── java │ └── cn │ └── mushuwei │ └── storage │ ├── SeataStorageApplication.java #应用SpringBoot启动类 │ ├── api │ │ ├── StorageApi.java #库存调用Dubbo接口 │ │ └── dto │ │ └── CommodityDTO.java #库存数据传输类 │ ├── config │ │ └── SeataAutoConfig.java #Seata配置类 │ ├── dao │ │ └── StorageDao.java #库存持久化类 │ ├── entity │ │ └── StorageDO.java #库存持久化实体 │ ├── provider │ │ └── StorageApiImpl.java #库存调用Dubbo接口实现类 │ └── service │ ├── StorageService.java #库存业务操作逻辑类 │ └── impl │ └── StorageServiceImpl.java #库存业务操作逻辑实现类 └── resources ├── application.yml #应用配置文件 ├── mybatis │ └── storage.xml #mybatis xml文件 └── sql └── storage.sql #数据库表结构和初始化数据 15 directories, 12 files Pom.xml <!-- 日志相关 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> </dependency> <!-- web服务相关 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- mysql数据库连接 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <!-- dubbo微服务框架 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> </dependency> <!-- 使用 Zookeeper 作为注册中心 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <!-- seata 相关依赖--> <dependency> <groupId>io.seata</groupId> <artifactId>seata-spring-boot-starter</artifactId> </dependency> 应用配置文件 # dubbo配置项,对应DubboConfigurationProperties 配置类 dubbo: application: name: ${spring.application.name} #应用名 registry: address: zookeeper://127.0.0.1:2181 #注册中心地址 timeout: 1000 # 指定注册到zk上超时时间,ms protocol: port: 20881 # 协议端口。使用 -1表示随机端口 name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 文档 scan: base-packages: cn.mushuwei.storage # 指定实现服务的包 server: port: 8081 #数据源配置 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/storage?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false username: root password: 123456 type: com.alibaba.druid.pool.DruidDataSource application: name: seata-action-storage #应用名 # seata相关配置 seata: service: grouplist: default: 127.0.0.1:8091 vgroup-mapping: service_tx_group: default enable-degrade: false disable-global-transaction: false enabled: true application-id: ${spring.application.name} tx-service-group: service_tx_group client: tm: commit-retry-count: 3 rollback-retry-count: 3 enable-auto-data-source-proxy: false rm: report-success-enable: true table-meta-check-enable: true report-retry-count: 5 async-commit-buffer-limit: 1000 transport: # Netty相关配置start type: TCP server: NIO heartbeat: true serialization: seata compressor: none enable-client-batch-send-request: true #客户端事务消息请求是否批量合并发送(默认true) shutdown: wait: 3 thread-factory: boss-thread-prefix: NettyBoss worker-thread-prefix: NettyServerNIOWorker server-executor-thread-prefix: NettyServerBizHandler share-boss-worker: false client-selector-thread-prefix: NettyClientSelector client-selector-thread-size: 1 client-worker-thread-prefix: NettyClientWorkerThread #数据库sql操作打印日志 logging: level: cn.mushuwei.storage.dao: debug 创建表结构和初始化数据 # 创建商品库存表 create table if not exists storage.storage ( id bigint auto_increment primary key, commodity_code varchar(50) null comment '商品编码', name varchar(255) null comment '商品名称', count int null comment '商品库存数' ); INSERT INTO storage.storage (id, commodity_code, name, count) VALUES (1, 'cola', '可口可乐', 2000); # 新建undo_log表 create table if not exists storage.undo_log ( id bigint auto_increment primary key, branch_id bigint not null, xid varchar(100) not null, context varchar(128) not null, rollback_info longblob not null, log_status int not null, log_created datetime not null, log_modified datetime not null, ext varchar(100) null, constraint ux_undo_log unique (xid, branch_id) ) charset=utf8;