开发工具idea、jdk8,redis、maven
首先用idea搭建eureka-server
配置文件:
server.port=8761
eureka.instance.hostname=127.0.0.1
eureka.instance.prefer-ip-address=true
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false
启动eureka-server
然后下载tx-lcn事务lcn4.1.0下载,选择-sprinfboot2.0.x分支进行下载
项目目录入上图,将该项目整体进行打包安装到maven本地仓库
找到刚下载的项目位置,进入到如图的目录文件夹内,按住ctrl+shift+鼠标右键 选择命令窗口,运行mvn package (maven环境变量要配置,否则找不到命令)这时maven会生成4.2.0版本的lcn
创建两个服务A,事务发起方
配置文件如下
eureka.client.serviceUrl.defaultZone= http://127.0.0.1:8761/eureka/
server.port= 8088
spring.application.name=service-hi
eureka.client.registerWithEureka=true
eureka.client.fetchRegistry=true
spring.thymeleaf.cache=false
spring.thymeleaf.enabled=false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/work?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
spring.datasource.maxWait=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.filters=stat,wall,log4j
mybatis.mapper-locations=classpath:mapper/*.xml
#Ribbon的负载均衡策略
ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
ribbon.MaxAutoRetriesNextServer=0
#txmanager地址
tm.manager.url=http://127.0.0.1:9010/tx/manager/
logging.level.com.codingapi=debug
tm.manager.url为事务协调者服务的url
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>service1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>service1</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
<lcn.last.version>4.2.0</lcn.last.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--分布式事物-->
<dependency>
<groupId>com.codingapi</groupId>
<artifactId>tx-client</artifactId>
<version>${lcn.last.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.codingapi</groupId>
<artifactId>transaction-springcloud</artifactId>
<version>${lcn.last.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.codingapi</groupId>
<artifactId>tx-plugins-db</artifactId>
<version>${lcn.last.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.8</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
启动类,@EnableFeignClients注解一定要加扫描com.codingapi.tx包,否则因扫描不到jar内的feignclient导致报错
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
@EnableFeignClients(basePackages = {"com.example.service1.client","com.codingapi.tx"})
@MapperScan("com.example.service1.dao")
public class Service1Application {
public static void main(String[] args) {
SpringApplication.run(Service1Application.class, args);
}
}
@Autowired
private com.example.service1.client.TbUserService userService;
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
@TxTransaction(isStart = true)
@Transactional(rollbackFor = Exception.class)
@Override
public boolean deleteById(String id,String exFlag) {
int i = tbUserDao.deleteById(id);
Result del = userService.del("2");
int a = 1/0;
return true;
}
@FeignClient(value = "service-hi2",fallback = TbUserServiceImpl.class)
public interface TbUserService {
@RequestMapping(value = "/tbUser/del")
public Result del(String id);
@RequestMapping(value = "/tbUser/update")
public Result update(@RequestBody TbUserDTO userDTO);
}
class TbUserServiceImpl implements TbUserService{
@Override
public Result del(String id) {
return Result.error(10001,"请稍后重试");
}
@Override
public Result update(TbUserDTO userDTO) {
return Result.error(10001,"请稍后重试");
}
}
服务B,事务参与方
配置文件
eureka.client.serviceUrl.defaultZone= http://127.0.0.1:8761/eureka/
server.port= 8089
spring.application.name=service-hi2
eureka.client.registerWithEureka=true
eureka.client.fetchRegistry=true
feign.hystrix.enabled=true
spring.thymeleaf.cache=false
spring.thymeleaf.enabled=false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/work?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
spring.datasource.maxWait=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.filters=stat,wall,log4j
mybatis.mapper-locations=classpath:mapper/*.xml
#Ribbon的负载均衡策略
ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
ribbon.MaxAutoRetriesNextServer=0
#txmanager地址
tm.manager.url=http://127.0.0.1:9010/tx/manager/
logging.level.com.codingapi=debug
pom文件同serviceA的pom文件
main方法
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
@EnableFeignClients(basePackages = {"com.example.service1.client","com.codingapi.tx"})
@MapperScan("com.example.service2.dao")
public class Service2Application {
public static void main(String[] args) {
SpringApplication.run(Service2Application.class, args);
}
}
feign调用http接口
/**
* 删除
* @param id
* @return
*/
@RequestMapping("/del")
@ResponseBody
public Result del(String id){
try {
tbUserService.deleteById("2");
}catch (Exception e){
return Result.ok(10001,"系统错误");
}
return Result.ok();
}
service:
*/
@TxTransaction
@Transactional(rollbackFor = Exception.class)
@Override
public boolean deleteById(String id) {
return tbUserDao.deleteById(id) > 0;
}
两个服务都配置好了,然后启动事务协调者,第一张图的tx-manager项目,启动成功后可以测试

结果,成功

两条数据都正常存在
eureka源码 :git@gitlab.com:boss_along/lcn-eureka.git
serviceA服务发起方git@gitlab.com:boss_along/lcn-service-a.git
serviceB服务参与方 git@gitlab.com:boss_along/lcn-service-b.git
本文详细介绍如何使用IDEA、JDK8、Redis、Maven等工具搭建微服务架构,并实现分布式事务处理。通过具体步骤指导搭建Eureka服务注册中心,下载并配置LCN分布式事务管理器,以及创建两个服务A和B,演示事务发起方和服务参与方的配置与交互。此外,还提供了POM文件、启动类、服务接口等关键代码片段。
361

被折叠的 条评论
为什么被折叠?



