查看原文
其他

介绍一个分布式事务框架项目

Java之间 2019-04-26

点击上方Java之间”,择“置顶或者星标”

你关注的就是我关心的!

在企业架构达到一定地步时,分布式事务是不可避免的一个技术难点,也是每一个分布式系统架构中都会涉及到的一个东西,特别是在微服务架构中,几乎可以说是无法避免,本文介绍的分布式事务框架项目名称为tx-lcn,这个框架目前最新版本为v4.0。

"LCN并不生产事务,LCN只是本地事务的协调者"

框架介绍

LCN分布式事务框架的核心功能是对本地事务的协调控制,框架本身并不创建事务,只是对本地事务做协调控制。因此该框架与其他第三方的框架兼容性强,支持所有的关系型数据库事务,支持多数据源,支持与第三方数据库框架一块使用(例如 sharding-jdbc),在使用框架的时候只需要添加分布式事务的注解即可,对业务的侵入性低。LCN框架主要是为微服务框架提供分布式事务的支持,在微服务框架上做了进一步的事务机制优化,在一些负载场景上LCN事务机制要比本地事务机制的性能更好,4.0以后框架开方了插件机制可以让更多的第三方框架支持进来。

框架特点

  • 支持各种基于spring的db框架

  • 兼容SpringCloud、Dubbo、motan

  • 使用简单,低依赖,代码完全开源

  • 基于切面的强一致性事务框架

  • 高可用,模块可以依赖RPC模块做集群化,TxManager也可以做集群化

  • 支持本地事务和分布式事务共存

  • 支持事务补偿机制,增加事务补偿决策提醒

  • 添加插件拓展机制

使用说明

分布式事务发起方:

    @Override
    @TxTransaction(isStart=true)
    @Transactional
    public boolean hello() {
        //本地调用
        testDao.save();
        //远程调用方
        boolean res =  test2Service.test();
        //模拟异常
        int v = 100/0;
        return true;
    }


分布式事务被调用方(test2Service的业务实现类)

    @Override
    @Transactional
    @TxTransaction
    public boolean test() {
        //本地调用
        testDao.save();
        return true;
    }

如上代码执行完成以后两个模块都将回滚事务。

说明:在使用LCN分布式事务时,只需要将事务的开始方法添加@TxTransaction(isStart=true)注解即可,在参与方添加@TxTransaction或者实现ITxTransaction接口即可。详细见demo教程

关于@TxTransaction 使用说明

@TxTransaction注解是分布式事务的标示。

若存在业务方法:a->b b->c b->d,那么开启分布式事务注解的话,需要在各个模块方法上添加@TxTransaction即可。

    @TxTransaction(isStart=true)
    @Transactional
    public void a(){
        b();
    }

    @TxTransaction
    public void b(){
        c();
        d();
    }

    @TxTransaction
    public void c(){}

    @TxTransaction
    public void d(){}

LCN原理

核心步骤

  • 创建事务组
    是指在事务发起方开始执行业务代码之前先调用TxManager创建事务组对象,然后拿到事务标示GroupId的过程。

  • 添加事务组
    添加事务组是指参与方在执行完业务方法以后,将该模块的事务信息添加通知给TxManager的操作。

  • 关闭事务组
    是指在发起方执行完业务代码以后,将发起方执行结果状态通知给TxManager的动作。当执行完关闭事务组的方法以后,TxManager将根据事务组信息来通知相应的参与模块提交或回滚事务。

事务控制原理


LCN事务控制原理是由事务模块TxClient下的代理连接池与TxManager的协调配合完成的事务协调控制。

TxClient的代理连接池实现了javax.sql.DataSource接口,并重写了close方法,事务模块在提交关闭以后TxClient连接池将执行"假关闭"操作,等待TxManager协调完成事务以后在关闭连接。

对于代理连接池的优化

  • 自动超时机制
    任何通讯都有最大超时限制,参与模块在等待通知的状态下也有最大超时限制,当超过时间限制以后事务模块将先确认事务状态,然后再决定执行提交或者回滚操作,主要为了给最大资源占用时间加上限制。

  • 智能识别创建不同的连接 对于只读操作、非事务操作LCN将不开启代理功能,返回本地连接对象,对于补偿事务的启动方将开启回滚连接对象,执行完业务以后马上回滚事务。

  • LCN连接重用机制 当模块在同一次事务下被重复执行时,连接资源会被重用,提高连接的使用率

事务补偿机制

为什么需要事务补偿?

事务补偿是指在执行某个业务方法时,本应该执行成功的操作却因为服务器挂机或者网络抖动等问题导致事务没有正常提交,此种场景就需要通过补偿来完成事务,从而达到事务的一致性。

补偿机制的触发条件?

当执行关闭事务组步骤时,若发起方接受到失败的状态后将会把该次事务识别为待补偿事务,然后发起方将该次事务数据异步通知给TxManager。TxManager接受到补偿事务以后先通知补偿回调地址,然后再根据是否开启自动补偿事务状态来补偿或保存该次切面事务数据。

补偿事务机制?

LCN的补偿事务原理是模拟上次失败事务的请求,然后传递给TxClient模块然后再次执行该次请求事务。

模拟场景演示

若存在事务发起方、参与方A、参与方B。调用关系图如下 

那么他们正常执行业务的时序图为:

若参与方B出现异常,那么他们的业务时序图为:

若他们的调用关系是这样的情况

此时发生参与方B出现异常时他们的时序图为:

结尾

通过框架的介绍和原理的分析,是不是还不够过瘾,那就赶紧下载源码实战吧。

官方网址:https://www.txlcn.org/

github地址:https://github.com/codingapi/tx-lcn

项目目录:

demo演示教程

每个demo下有区分为 jdbc/hibernate/mybatis不同框架的版本demo

springcloud版本   https://github.com/codingapi/springcloud-lcn-demo

dubbo版本  https://github.com/codingapi/dubbo-lcn-demo

小编也就用过springcloud版本,更多解锁姿势希望大家去发掘,觉得不错的话可以给项目加个Star.

最近热文阅读:

1、呕心沥血3年为大家整理了40页高频面试题!

2、Java后端技术从0到1技术路线,一步步走向大神!

3、这些NB哄哄的分布式任务调度系统,你用过几个?

4、HashMap是怎样hash的?又是如何map的?

5、彻底理解分布式Netty,这一篇文章就够了!

6数据库性能优化的误区!

7、阿里员工的Java问题排查工具单!

关注公众号,你想要的Java都在这里!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存