基于springboot 2.2.2+sharding+seata实现分布式事务

本文介绍了在微服务环境下,如何利用SpringBoot 2.2.2、Sharding和Seata的AT模式实现分布式事务。详细讲解了Seata AT过程模型、集成架构、各服务的配置以及业务场景,包括采购送货单、采购计划和采购需求服务的实现,展示了正常和异常业务的测试案例。
摘要由CSDN通过智能技术生成

一、背景
  1.1 分布式事务产生
  在微服务环境下,我们会根据不同的业务拆分成不同的服务,比如采购订单服务、采购送货单服务、供应商管理服务等。每个服务都有自己独立的数据库并且是独立运行的,互不影响。服务与服务之间通讯采用RPC远程调用技术。每个服务中都有自己独立的数据源,也就是自己独立的本地事务。两个服务之间相互通讯的时候,两个本地事务互不影响,从而就出现了分布式事务。
  1.2 模式选择
  分布式事务框架有很多,本解决方案基于seata框架的AT模式实现分布式事务控制,同时seata也支持tcc和saga模式,由于这两种模式在代码量和技术难度上都要求较高,在选择时可以根据实际业务场景需求进行,在此也提供柔性事务选择取舍特征。有关分布式事务的其他模式,在此不做详细赘述。
柔性事务选择取舍特征:
在这里插入图片描述

使用AT模式有两个前提需要提前注意的:
    1.基于支持本地ACID事务的关系型数据库。
    2.Java应用,通过JDBC访问数据库。
  1.3 系统架构
  Seata AT过程模型如下:
 在这里插入图片描述
  Sharding和Seata集成架构图:
  在这里插入图片描述
  1.4 业务场景
  在采购业务领域中有一项业务是创建送货单,在创建送货单时要进行业务逻辑判断,是不是VMI的送货单,如果是,此时需要创建采购计划。在创建采购计划时也需要判断计划的来源是不是VMI,如果是,需要创建采购需求。业务流程图如下:
在这里插入图片描述

以上业务场景对真实业务场景做了脱敏。
二、java代码
  2.1 技术栈
  代码技术栈使用:spring boot 2.2.2、mybatis2.1.3、druid1.1.10、sharding4.1.0、mysql5.7、idgenerator1.4.2、eureka2.2.1、openfeign2.2.1、seata1.2、分布式事务服务端使用seata1.3。
  2.2 采购送货单服务
  2.2.1 工程结构
在这里插入图片描述
  2.2.2 pom文件依赖包

<dependencies>
		<!-- spring boot包引入 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<!-- mybatisplus依赖包引入,引入MyBatis-Plus之后请不要再次引入 MyBatis 以及 MyBatis-Spring,以避免因版本差异导致的问题。 -->
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.1.2</version>
		</dependency>
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus</artifactId>
			<version>3.1.2</version>
		</dependency>
		<!-- mybatis分页插件 -->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper-spring-boot-starter</artifactId>
			<version>1.2.12</version>
		</dependency>
		<!-- mysql驱动包依赖包引入 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<!-- druid连接池依赖包引入 -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>1.1.10</version>
		</dependency>
		<!-- sharding-jdbc数据库读写分离依赖包引入 -->
		<dependency>
			<groupId>org.apache.shardingsphere</groupId>
			<artifactId>sharding-jdbc-core</artifactId>
			<version>4.1.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shardingsphere</groupId>
			<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
			<version>4.1.0</version>
		</dependency>
		<!-- 使用sharding的BASE事务依赖包引入 -->
		<dependency>
			<groupId>org.apache.shardingsphere</groupId>
			<artifactId>sharding-transaction-base-seata-at</artifactId>
			<version>4.1.0</version>
		</dependency>
		<!-- sharding学花算法实现的全局分布式ID依赖包引入 -->
		<dependency>
			<groupId>com.dangdang</groupId>
		<artifactId>sharding-jdbc-self-id-generator</artifactId>
			<version>1.4.2</version>
		</dependency>
		<!-- seata分布式事务依赖引入 -->
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-alibaba-seata</artifactId>
			<version>2.2.0.RELEASE</version>
			<exclusions>
				<exclusion>
					<artifactId>seata-all</artifactId>
					<groupId>io.seata</groupId>
				</exclusion>
			</exclusions>
		</dependency>
		<!-- 不使用stater中依赖的seata,使用1.2.0版本 -->
		<dependency>
			<groupId>io.seata</groupId>
			<artifactId>seata-all</artifactId>
			<version>1.2.0</version>
		</dependency>
		<dependency>
			<groupId>io.seata</groupId>
			<artifactId>seata-spring-boot-starter</artifactId>
			<version>1.2.0</version>
		</dependency>
		<!--eureka客户端依赖包引入 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
			<version>2.2.1.RELEASE</version>
		</dependency>
		<!--openfeign依赖包引入 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-openfeign</artifactId>
			<version>2.2.1.RELEASE</version>
		</dependency>			
	</dependencies>

2.2.3 application.properties文件配置

#服务端口
server.port=8081
#tomcat编码
server.tomcat.uri-encoding=UTF-8
spring.aop.proxy-target-class=true
spring.application.name=delivery-note
spring.cloud.alibaba.seata.tx-service-group=delivery-note-group
spring.main.allow-bean-definition-overriding=true
#表示是否将自己注册进EurekaServer默认为true
eureka.client.fetch-registry=true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
eureka.client.register-with-eureka=true
#eureka服务器地址单机
eureka.client.service-url.defaultZone=http://127.0.0.1:8181/eureka/
#注册到eureka中的服务名称
eureka.instance.instance-id=delivery-note
#访问路径可以显示IP地址
eureka.instance.prefer-ip-address=true
#feign客户端读取超时时间(单位:毫秒)
feign.client.config.default.read-timeout=15000

#feign客户端连接超时时间(单位:毫秒)
feign.client.config.default.connect-timeout=15000
#当OkToRetryOnAllOperations设置为false时,只会对get请求进行重试。如果设置为true,便会对所有的请求进行重试,如果是put或post等写操作,如果服务器接口没做幂等性,会产生不好的结果,所以OkToRetryOnAllOperations慎用。
ribbon.OkToRetryOnAllOperations=false
#数据源名称,多数据源以逗号分隔
spring.shardingsphere.datasource.names=master,slave0,slave1
#主数据源
#数据库连接池类名称
spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
#数据库驱动类名
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库URL连接
spring.shardingsphere.datasource.master.url=jdbc:mysql://192.168.145.183:3306/order?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
#数据库用户名
spring.shardingsphere.datasource.master.username=root
#数据库密码
spring.shardingsphere.datasource.master.password=123456
#初始化大小,最小,最大
spring.shardingsphere.datasource.master.initial-size=5
spring.shardingsphere.datasource.master.min-idle=5
spring.shardingsphere.datasource.master.max-active=20
#配置获取连接等待超时的时间
spring.shardingsphere.datasource.master.max-wait=60000
#从数据源
spring.shardingsphere.datasource.slave0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.slave0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.slave0.url=jdbc:mysql://192.168.145.184:3306/order?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
spring.shardingsphere.datasource.slave0.username=root
spring.shardingsphere.datasource.slave0.password=123456
#初始化大小,最小,最大
spring.shardingsphere.datasource.slave0.initial-size=5
spring.shardingsphere.datasource.slave0.min-idle=5
spring.shardingsphere.datasource.slave0.max-active=20
#配置获取连接等待超时的时间
spring.shardingsphere.datasource.slave0.max-wait=60000
#从数据源
spring.shardingsphere.datasource.slave1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.slave1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.slave1.url=jdbc:mysql://192.168.145.185:3306/order?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
spring.shardingsphere.datasource.slave1.username=root
spring.shardingsphere.datasource.slave1.password=123456
#初始化大小,最小,最大
spring.shardingsphere.datasource.slave1.initial-size=5
spring.shardingsphere.datasource.slave1.min-idle=5
spring.shardingsphere.datasource.slave1.max-active=20
#配置获取连接等待超时的时间
spring.shardingsphere.datasource.slave1.max-wait=6000
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值