优质网站建设,中国高等教育学生信息网,网上申报系统,哈尔滨网站建站模板有道无术#xff0c;术尚可求#xff0c;有术无道#xff0c;止于术。 本系列Seata 版本 2.0.0 本系列Spring Boot 版本 3.2.0 本系列Spring Cloud 版本 2023.0.0 源码地址#xff1a;https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 概述2. 多数据… 有道无术术尚可求有术无道止于术。 本系列Seata 版本 2.0.0 本系列Spring Boot 版本 3.2.0 本系列Spring Cloud 版本 2023.0.0 源码地址https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 概述2. 多数据源环境搭建2.1 数据库2.2 项目搭建 3. Seata 集成3.1 undo_log 表3.2 引入依赖3.3 配置3.4 添加注解3.5 测试 1. 概述
在之前的案例中我们在Spring Cloud微服务场景下使用Seata解决了分布式事务问题在单体架构中单个服务也可能存在跨库导致的分布式事务问题例如下图中因为分库导致下单请求需要连接多个数据库进行操作
2. 多数据源环境搭建
这里使用MyBatis-Plus开发团队提供的多数据源框架dynamic-datasource相关简介可参考官网。
2.1 数据库
使用的是Mysql 8.0.29首先创建三个数据库
seata_account账户seata_order订单seata_stock库存
seata_account库插入t_account表
CREATE TABLE t_account (id int NOT NULL AUTO_INCREMENT,user_id varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,amount double(14,2) DEFAULT 0.00,PRIMARY KEY (id)
) ENGINEInnoDB AUTO_INCREMENT2 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci;INSERT INTO t_account
(user_id, amount)
VALUES(1, 10000.00);seata_order库插入t_order表
CREATE TABLE t_order (id int NOT NULL AUTO_INCREMENT,order_no varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,user_id varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,commodity_code varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,count int DEFAULT 0,amount double(14,2) DEFAULT 0.00,PRIMARY KEY (id)
) ENGINEInnoDB AUTO_INCREMENT64 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci;seata_stock库插入t_stock表
CREATE TABLE t_stock (id int NOT NULL AUTO_INCREMENT,commodity_code varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,name varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,count int DEFAULT 0,PRIMARY KEY (id),UNIQUE KEY commodity_code (commodity_code)
) ENGINEInnoDB AUTO_INCREMENT2 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci;INSERT INTO t_stock
(commodity_code, name, count)
VALUES(IPHONE, 苹果手机, 10000);2.2 项目搭建
注意这里省略了一些简单代码完整代码请参考案例源码
项目技术栈
JDK 17Maven 3.6.3Seata 2.0 Mybatis Plus 3.5.5 Dynamic Datasource 4.3.0 Spring Boot 3.2.0
使用Spring Initializr创建一个Spring Boot服务项目引入相关依赖 dependencies!--Spring Boot Web--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!--工具--dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependencydependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion5.7.21/version/dependency!--Mybatis Plus--dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-spring-boot3-starter/artifactIdversion3.5.5/version/dependency!-- https://mvnrepository.com/artifact/com.baomidou/dynamic-datasource-spring-boot-starter --dependencygroupIdcom.baomidou/groupIdartifactIddynamic-datasource-spring-boot3-starter/artifactIdversion4.3.0/version/dependencydependencygroupIdcom.mysql/groupIdartifactIdmysql-connector-j/artifactIdscoperuntime/scope/dependency/dependencies添加多数据源配置
server:port: 9000
spring:application:name: dynamic-datasource-seata-demodatasource:dynamic:hikari:minimum-idle: 5idle-timeout: 30000maximum-pool-size: 20max-lifetime: 1800000connection-timeout: 50000primary: d_accountdatasource:d_account:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/seata_account?zeroDateTimeBehaviorconvertToNulluseUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/ShanghaiautoReconnecttrueusername: rootpassword: 123456d_order:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/seata_order?zeroDateTimeBehaviorconvertToNulluseUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/ShanghaiautoReconnecttrueusername: rootpassword: 123456d_stock:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/seata_stock?zeroDateTimeBehaviorconvertToNulluseUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/ShanghaiautoReconnecttrueusername: rootpassword: 123456各个Mapper接口添加DS注解
DS(d_account)
DS(d_order)
DS(d_stock)BusinessService服务添加下单功能 public Object handleBusiness() {// 1. 业务请求数据BusinessDTO businessDTO new BusinessDTO();businessDTO.setUserId(1); // 下单用户businessDTO.setCount(1); // 数量businessDTO.setCommodityCode(IPHONE); // 商品编号businessDTO.setAmount(new BigDecimal(1)); // 订单金额log.info(业务请求数据 businessDTO);// 2. 扣减库存 CommodityDTO commodityDTO new CommodityDTO();commodityDTO.setCommodityCode(businessDTO.getCommodityCode()); // 商品编号commodityDTO.setCount(businessDTO.getCount()); // 数量Object stock stockService.decreaseStock(commodityDTO);log.info(调用库存服务 stock);// 3. 创建订单OrderDTO orderDTO new OrderDTO();orderDTO.setUserId(businessDTO.getUserId());orderDTO.setCommodityCode(businessDTO.getCommodityCode());orderDTO.setOrderCount(businessDTO.getCount());orderDTO.setOrderAmount(businessDTO.getAmount());OrderDTO response orderService.createOrder(orderDTO);log.info(调用订单服务 response);return orderDTO;}3. Seata 集成
3.1 undo_log 表
在AT模式中需要在参与全局事务的数据库中添加undo_log表
-- seata_account.undo_log definitionCREATE TABLE undo_log (id bigint NOT NULL AUTO_INCREMENT COMMENT 主键ID,branch_id bigint NOT NULL COMMENT 分支事务ID,xid varchar(100) CHARACTER SET utf8mb3 COLLATE utf8_general_ci NOT NULL COMMENT 全局事务唯一标识,context varchar(128) CHARACTER SET utf8mb3 COLLATE utf8_general_ci NOT NULL COMMENT 上下文,rollback_info longblob NOT NULL COMMENT 回滚信息,log_status int NOT NULL COMMENT 状态0正常1全局已完成防悬挂,log_created datetime NOT NULL COMMENT 创建时间,log_modified datetime NOT NULL COMMENT 修改时间,PRIMARY KEY (id),UNIQUE KEY ux_undo_log (xid,branch_id)
) ENGINEInnoDB DEFAULT CHARSETutf8mb3 COMMENTAT模式回滚日志表;在seata_account、seata_order、seata_stock库中都新建undo_log表。
3.2 引入依赖
这里演示的是单机模式所以不需要注册中心、配置中心引入seata提供的Spring Boot启动包 dependencygroupIdio.seata/groupIdartifactIdseata-spring-boot-starter/artifactIdversion2.0.0/version/dependency3.3 配置
application.yml中配置使用file作为注册中心、配置中心
seata:# 配置中心config:type: filefile:name: file.conf# 注册中心registry:type: file多数据源配置开启Seata并设置事务模式 datasource:dynamic:seata: true # 启用Seataseata-mode: at # 事务模式支持AT、XAhikari:minimum-idle: 5在resources目录下添加file.conf配置文件内容如下
transport {# tcp udt unix-domain-sockettype TCP#NIO NATIVEserver NIO#enable heartbeatheartbeat true# the client batch send request enableenableClientBatchSendRequest true#thread factory for nettythreadFactory {bossThreadPrefix NettyBossworkerThreadPrefix NettyServerNIOWorkerserverExecutorThread-prefix NettyServerBizHandlershareBossWorker falseclientSelectorThreadPrefix NettyClientSelectorclientSelectorThreadSize 1clientWorkerThreadPrefix NettyClientWorkerThread# netty boss thread size,will not be used for UDTbossThreadSize 1#auto default pin or 8workerThreadSize default}shutdown {# when destroy server, wait secondswait 3}serialization seatacompressor none
}
service {#transaction service group mappingvgroupMapping.default_tx_group default#only support when registry.typefile, please dont set multiple addressesdefault.grouplist 127.0.0.1:8091#degrade, current not supportenableDegrade false#disable seatadisableGlobalTransaction false
}client {rm {asyncCommitBufferLimit 10000lock {retryInterval 10retryTimes 30retryPolicyBranchRollbackOnConflict true}reportRetryCount 5tableMetaCheckEnable falsereportSuccessEnable false}tm {commitRetryCount 5rollbackRetryCount 5}undo {dataValidation truelogSerialization jacksonlogTable undo_log}log {exceptionRate 100}
}file.conf中需要注意配置TC地址
3.4 添加注解
添加分布式事务注解GlobalTransactional GlobalTransactionalpublic Object handleBusiness() {//......}3.5 测试
启动Seata、后台服务查看日志可以看到成功连接TC并在AT模式下自动代理了数据源 当发生业务异常时可以看到多个RM都进行了回滚操作查看数据库也发现数据一致说明集成成功