springcloud整合LCN分布式事务

本文详细介绍如何使用IDEA、JDK8、Redis、Maven等工具搭建微服务架构,并实现分布式事务处理。通过具体步骤指导搭建Eureka服务注册中心,下载并配置LCN分布式事务管理器,以及创建两个服务A和B,演示事务发起方和服务参与方的配置与交互。此外,还提供了POM文件、启动类、服务接口等关键代码片段。

开发工具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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值