分布式事务之 LCN 框架实现方案的原理、配置与使用

LCN 原理

背景

LCN 名称是由早期版本的 LCN 框架命名,在设计框架之初的1.0~2.0的版本时框架设计的步骤是如下,各取其首字母得来的 LCN 命名。

  • 锁定事务单元(Lock)
  • 确认事务模块状态( Confirm)
  • 通知事务( Notify)

框架定位

LCN 并不生产事务,LCN 只是本地事务的协调工。TX-LCN 定位于一款事务协调性框架,框架其本身并不操作事务,而是基于对事务的协调从而达到事务一致性的效果。

事务控制原理

TX-LCN由两大模块组成, TxClient、 TxManager。

TxClient 作为模块的依赖框架,提供 TX-LCN 的标准支持, TxManager 作为分布式事务的控制方。事务发起方或者参与方都由 TxClient 来控制。

通过代理 Connection 的方式实现对本地事务的操作,然后在由 TxManager 统一协调控制事务。当本地事务提交回滚或者关闭连接时将会执行假操作,该代理的连接将由 LCN 连接池管理。

原理图

在这里插入图片描述

配置

依赖配置

<!--lcn事务-->
<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>

启动类配置

添加注解

@EnableDistributedTransaction

使用

配合 Dubbo 使用:

服务提供方

@com.alibaba.dubbo.config.annotation.Service
public class LcnReceiveServiceImpl implements ReceiveService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @LcnTransaction
    public void receiveMoney(int money) {
        int resultUser = jdbcTemplate.update("INSERT INTO bank_b(money,user_name)VALUES (?,?)",money,"peter");
        System.out.println(TracingContext.tracing().groupId());
    }
}

服务发现方

@Service
public class DubboTransferService implements TransferService{

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Reference
    private ReceiveService receiveService;

    @LcnTransaction
    public String transfer(int money) {
        int resultUser = jdbcTemplate.update("INSERT INTO bank_a(money,user_name)VALUES (?,?)",-money,"james");

        System.out.println(TracingContext.tracing().groupId());
        receiveService.receiveMoney(money);//隐藏地传递了groupid
        if (money > 20){
            throw new RuntimeException("money too large");
        }
        return resultUser+"-";
    }
}

可以看到,LCN 框架使用起来非常简单。在两个应用中,分别在方法上加上 @LcnTransaction 注解就可以了。这样,这两个事务就在同一个事务组里,要么 2 个事务都成功,要么都失败。

该模式缺陷在于代理的连接需要随事务发起方一起释放连接,增加了连接占用的时间。

TCC 原理

前面的 LCN 依赖包,其实也实现了 TCC 事务。

思想

TCC其实就是采用的补偿机制,其核心思想是:针对每个操作,都要注册一个与其业务逻辑对应的确认和补偿(撤销)操作。

其将整个业务逻辑的每个分支显式的分成了 Try、 Confirm、 Cancel 三个操作。Try 部分完成业务的准备工作, Confirm 部分完成业务的提交, Cancel 部分完成事务的回滚。

原理图

在这里插入图片描述

使用

服务提供方

@com.alibaba.dubbo.config.annotation.Service
public class TccReceiveServiceImpl implements ReceiveService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    //try   
    @TccTransaction(confirmMethod = "confirm", cancelMethod = "cancel", executeClass = TccReceiveServiceImpl.class)
    public void receiveMoney(int money) {
        String groupId = TracingContext.tracing().groupId();
        int resultUser = jdbcTemplate.update("INSERT INTO bank_b(money,user_name,status)VALUES (?,?,?)",money,"peter",groupId);
    }
    
    public void confirm(int money) {
        String groupId = TracingContext.tracing().groupId();
        int resultUser = jdbcTemplate.update("UPDATE bank_b SET status = 1 WHERE status = ?", tracing().groupId());
    }
    
    public void cancel(int money) {
        String groupId = TracingContext.tracing().groupId();
        int resultUser = jdbcTemplate.update("INSERT INTO bank_b(money,user_name,status)VALUES (?,?,?)",-money,"peter",groupId);
    }
}

可以看到,和 LCN 相比,程序员需要写大量的补偿方法,这是它的缺点。

它的优点和 LCN 一样,没有实现真正的 “事务”。真正的事务,如 “二阶段提交”、“三阶段提交”,对响应时间上不如 LCN、TCC 这种变相实现的 “事务”。

关于 “二阶段提交”、“三阶段提交”,见
zookeeper 相关协议、集群特点

©️2020 CSDN 皮肤主题: 岁月 设计师: pinMode 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值