分布式事务-tx-lcn 强一致性。

1.介绍

    LCN并不生产事务,LCN只是本地事务的协调工,LCN是一个高性能的分布式事务框架,兼容dubbo、springcloud框架,支持RPC框架拓展,支持各种ORM框架、NoSQL、负载均衡、事务补偿

    a、强一致性,通过TxManager协调控制与事务补偿机制确保数据一致性(主要特点,强一致性,比消息事务强的方面)。

    b、易用性,仅需要在业务方法上添加相应注解即可,有个简易的可视化界面。

    c、高可用,项目模块不仅可高可用部署,事务协调器也可集群化部署。

2.流程图

3.关键组件:

eureka-server:服务注册与发现。

txlcn-tm:txlcn的事务管理器,可直接用的jar包(txlcn-tm-0.0.1.jar_txmanager如何保证一致性-Java文档类资源-CSDN下载,需修改配置文件地址和端口)。

service-a:springcloud 2.1.0,服务a,操作数据库及调用服务b1。

service-b1:springcloud 2.1.0,服务b1,操作数据库。

redis

4.github代码:https://github.com/kickTec/springCloudDemo/tree/tx-lcn

csdn下载:spring-txlcn.zip-Java文档类资源-CSDN下载

5.service-a/service-b1关键依赖

        <!-- txlcn分布式事务管理 -->
        <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>

        <!--lombok插件 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

6.service-a关键代码

    @LcnTransaction//分布式事务
    @Override
    public String txlcn(String exFlag) {
        //先调用本地服务,新增一个用户user PS:调用EntityManager的merge,传进去的实体字段是什么就保存什么
        TbUser tbUser = new TbUser();
        tbUser.setUsername("tx-lcn-"+exFlag);
        tbUser.setPassword("123456");
        TbUser user = entityManager.merge(tbUser);
        System.out.println(user);

        //调用B服务,新增一个用户描述description
        TbDescription description1 = bFeign.txlcn(user.getId());
        System.out.println(description1);

        if("catchNull".equals(exFlag) && description1 == null){
            throw new RuntimeException("服务2异常!");
        }

        if("numExcepiton".equals(exFlag)){
            int num = 1/0;
        }

        //根据标识,是否抛出异常
        if (!StringUtils.isEmpty(exFlag)) {
            return "操作成功,请查看一下数据库验证!";
        } else {
            throw new RuntimeException("rollback transactional by exFlag");
        }
    }

service-b1关键代码

    @LcnTransaction//分布式事务
    @Override
    public TbDescription txlcn(Integer userId){
        TbDescription tbDescription = null;
        try{
            tbDescription = entityManager.find(TbDescription.class, userId);
            if(tbDescription == null){
                tbDescription = new TbDescription();
                tbDescription.setId(userId);
                tbDescription.setUserId(userId);
                tbDescription.setDescription("服务B设置的描述");
            }else{
                tbDescription.setDescription(tbDescription.getDescription()+",服务B设置的描述");
            }
            tbDescription = entityManager.merge(tbDescription);
            int num = 1/0;
        }catch (Exception e){
            tbDescription = null;
            System.out.println(e.getMessage());
        }
        return tbDescription;
    }

7.执行流程

7.1 数据库文件使用https://github.com/kickTec/springCloudDemo/tree/tx-lcn中的test.sql。

7.2 依次启动eureka 、txlcn-tm、service-a、service-b1;

7.3 正常业务:调用a服务的txlcn接口,会在本地持久化一条tbuser数据(username跟着传递的参数变化);再调用b1服务的txlcn接口,新增一条tbdescription数据(userId为前面a服务持久化的userId)。

调用A服务接口:http://192.168.0.18:10081/txlcn?exFlag=kenick01

A服务打印的日志:

b1服务日志:

7.4 异常情况

a服务本地持久化成功,并且调用b服务成功,a服务后续发生异常;调用服务a接口:http://192.168.0.18:10081/txlcn?exFlag=numExcepiton。

a服务日志分析:

b服务日志分析:

另一种事务异常情况:

a服务持久化数据成功,b服务持久化数据失败。在b服务的业务中增加产生异常的代码,注意:如果b服务产生的异常在controller层被捕获了(很有可能),此时A服务获取到B服务的结果,但是没捕获到异常,会造成A服务不回滚(若B服务controller层不捕获异常,则可以回滚,这个是机制问题,感觉后续可以优化,影响不大)。

int num = 1/0; // 抛出异常

a服务日志:

b服务日志:

评价:通过中间件tx-lcn-tm管理事务,使用代理本地数据库连接的方式,控制不同服务的事务提交和回滚,能够实现较好的强一致性;不足之处,不同服务之间的管理会增加额外开销,同时由于必须等待多个服务都处理完毕,事务才会提交回滚,会造成数据库资源锁定时间变长,这点需要注意。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kenick

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值