欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringBoot-LCN5.0.2分布式事务框架整合

程序员文章站 2022-05-07 18:46:19
...

LCN分布式事务框架整合

场景图:我们是要在订单服务中,调用库存服务。当下一个订单的时候,就对库存-1操作

SpringBoot-LCN5.0.2分布式事务框架整合

1、首先要把tx-manager(分布式协调者)项目搭建起来

我这里使用的是最新的lcn版本依赖

   <dependency>
            <groupId>com.codingapi.txlcn</groupId>
            <artifactId>txlcn-tm</artifactId>
            <version>5.0.2.RELEASE</version>
   </dependency>

pom.xml文件

spring.application.name=tx-manager
server.port=8899
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tx-manager?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123456
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.use-generated-keys=true
#tx-lcn.logger.enabled=true
# TxManager Host Ip
#tx-lcn.manager.host=127.0.0.1
# TxClient连接请求端口 这个地方一定要进行开放
tx-lcn.manager.port=8070
# 心跳检测时间(ms)
tx-lcn.manager.heart-time=15000
# 分布式事务执行总时间
tx-lcn.manager.dtx-time=100000
#参数延迟删除时间单位ms
#tx-lcn.message.netty.attr-delay-time=10000
#tx-lcn.manager.concurrent-level=128
# 开启日志
tx-lcn.logger.enabled=true
logging.level.com.codingapi=debug
#redis 主机
spring.redis.host=127.0.0.1
#redis 端口
spring.redis.port=6379
#redis 密码
spring.redis.password=123456
# eureka地址
eureka.client.service-url.defaultZone=http://127.0.0.1:8100/eureka/
eureka.instance.prefer-ip-address=true
# TM后台登陆密码,默认值为codingapi
tx-lcn.manager.admin-key=admin


tx-manager项目启动类

@SpringBootApplication
@EnableTransactionManagerServer
@EnableEurekaClient
public class TransactionManagerApplication {

    public static void main(String[] args) {
        SpringApplication.run(TransactionManagerApplication.class, args);
    }

}

3、融入服务中,这里我使用 order服务和stock服务

在要使用LCN分布式框架的服务中导入依赖

 <!--        引入分布式事务解决框架LCN start-->

        <dependency>
            <groupId>com.codingapi.txlcn</groupId>
            <artifactId>txlcn-tc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>com.codingapi.txlcn</groupId>
            <artifactId>txlcn-txmsg-netty</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!--        引入分布式事务解决框架LCN end-->

Order启动类:

/**
 * 订单服务
 *
 * @author liyue
 * @date 2019/12/9 12:11
 */
@EnableEurekaClient
@SpringBootApplication
@EnableFeignClients
@MapperScan(basePackages = "com.leeue.mapper")
/**TC开启分布式事务注解**/
@EnableDistributedTransaction
public class OrderApp {

    public static void main(String[] args) {
        SpringApplication.run(OrderApp.class, args);
    }
}

order方法实现类

@LcnTransaction //分布式事务注解
@Transactional(rollbackFor = Exception.class)//事务注解 
@Override
public ResponseBase addOrderAndStock(int i) throws Exception {
    OrderEntity orderEntity = new OrderEntity();
    orderEntity.setName("永久会员充值");
    orderEntity.setOrderCreatetime(new Date());
    // 价格是300元
    orderEntity.setOrderMoney(300d);
    // 状态为 未支付
    orderEntity.setOrderState(0);
    Long commodityId = 30L;
    // 商品id
    orderEntity.setCommodityId(commodityId);
    // 1.先下单,创建订单
    int orderResult = orderMapper.addOrder(orderEntity);
    System.out.println("orderResult:" + orderResult);
    // 2.下单成功后,调用库存服务
    ResponseBase inventoryReduction = stockFeign.inventoryReduction(commodityId);
    if (inventoryReduction.getRtnCode() != 200) {
        // 第一种方法,使用手动事务 -
        //  TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        // 第二种方法,使用aop,捕获异常后,进行手动事务回滚,获取将异常抛出给上一层,外面回滚。
        throw new Exception("调用库存服务接口失败,开始回退订单事务代码");
    }
    int reuslt = 1 / i;
    return setResultSuccess("下单成功!");
}

同理:

Stock启动类

/**
 * 库存服务
 *
 * @author liyue
 * @date 2019/12/9 12:13
 */
@EnableEurekaClient
@SpringBootApplication
@EnableFeignClients
@MapperScan(basePackages = "com.leeue.mapper")
/**TC开启分布式事务注解**/
@EnableDistributedTransaction
public class StockApp {
    public static void main(String[] args) {
        SpringApplication.run(StockApp.class, args);
    }
}

stock实现方法:

@LcnTransaction //分布式事务注解
@Transactional
@RequestMapping("/inventoryReduction")
public ResponseBase inventoryReduction(@RequestParam("commodityId") Long commodityId) {
    if (commodityId == null) {
        return setResultError("商品id不能为空!");
    }
    // 1.查询该商品id 是否存在
    StockEntity stockEntity = stockMapper.selectStock(commodityId);
    if (stockEntity == null) {
        return setResultError("商品id不存在!");
    }
    // 2.判断商品是否有超卖
    if (stockEntity.getStock() <= 0) {
        return setResultError("当前商品已经买完啦!");
    }
    // 3.减去库存1
    int updateStockResult = stockMapper.updateStock(commodityId);
    if (updateStockResult <= 0) {
        return setResultError("修改库存失败!");
    }
    return setResultSuccess("修改库存成功!");
}

搭建中遇到了问题:

Connect socket(/127.0.0.1:8070) fail. 6000ms latter try again.

这个问题其实是我tx-manager项目中配置文件这个没有打开 这个地方一定要开放出来

# TxClient连接请求端口 这个地方一定要进行开放
tx-lcn.manager.port=8070

如果其他情况可以查看官网git

https://github.com/codingapi/tx-lcn/issues/261

Tx-manager后台管理地址:http://127.0.0.1:8899/admin/index.html#/TxClient

如果tx-manager突然挂了:

  • 1、后台会报异常,non tx-manager is alive
  • 2、如果在提交的时候tx-manager突然挂了,事务还是会进行回滚,因为开始的都是假提交,没有真正的提交的都会出现事务的回滚。

搭建源码:

SpringBoot-LCN5.0.2分布式事务框架整合

相关标签: 分布式事务