分布式事务基础介绍

本文探讨了分布式系统中的事务处理难点,包括数据库事务的ACID特性,以及CAP定理和BASE理论的应用。重点介绍了两阶段提交、TCC方案和基于消息的最终一致性等分布式事务解决方案,以及阿里巴巴GTS在实际应用中的例子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、简介

分布式事务是企业集成中的一个技术难点,也是每一个分布式系统架构中都会涉及到的一个东西,特别是在微服务架构中,几乎可以说是无法避免。

二、数据库事务

数据库事务的几个特性:原子性(Atomicity )、一致性( Consistency )、隔离性或独立性( Isolation)和持久性(Durabilily),简称就是ACID。

分布式的网络环境很复杂,容易出现的问题:

机器宕机、网络异常、消息丢失、消息乱序、数据错误、不可靠的TCP、存储数据丢失...

三、分布式系统CAP与BASE

CAP定理

CAP定理是由加州大学伯克利分校Eric Brewer教授提出来的,他指出WEB服务无法同时满足一下3个属性:

一致性(Consistency) : 客户端知道一系列的操作都会同时发生(生效)

可用性(Availability) : 每个操作都必须以可预期的响应结束

分区容错性(Partition tolerance) : 即使出现单个组件无法可用,操作依然可以完成

关系型数据库选择CA

非关系型数据库选择CP

Cassandra:选择是AP

BASE理论

在分布式系统中,我们往往追求的是可用性,它的重要程序比一致性要高,那么如何实现高可用性呢? 前人已经给我们提出来了另外一个理论,就是BASE理论,它是用来对CAP定理进行进一步扩充的。BASE理论指的是:

Basically Available(基本可用)

Soft state(软状态)

Eventually consistent(最终一致性)

BASE理论是对CAP中的一致性和可用性进行一个权衡的结果,理论的核心思想就是:我们无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。

四、分布式事务解决方案

1、基于XA协议的两阶段提交方案

交易中间件与数据库通过 XA 接口规范,使用两阶段提交来完成一个全局事务, XA 规范的基础是两阶段提交协议。

第一阶段是表决阶段,所有参与者都将本事务能否成功的信息反馈发给协调者;

第二阶段是执行阶段,协调者根据所有参与者的反馈,通知所有参与者,步调一致地在所有分支上提交或者回滚。

LCN;分布式事务框架 https://github.com/codingapi/tx-lcn/wiki

2、TCC方案

TCC方案在电商、金融领域落地较多。TCC方案其实是两阶段提交的一种改进。其将整个业务逻辑的每个分支显式的分成了Try、Confirm、Cancel三个操作。Try部分完成业务的准备工作,confirm部分完成业务的提交,cancel部分完成事务的回滚。基本原理如下图所示。

3、基于消息的最终一致性方案

4、阿里的GTS (收费)

在业务函数外围使用@TxcTransaction注解即可开启分布式事务。Dubbo应用通过隐藏参数将GTS的事务xid传播到服务端。

@TxcTransaction(timeout = 1000 * 10)

public void Bussiness(OrderService orderService, StockService stockService, String userId) {

    //获取事务上下文

    String xid = TxcContext.getCurrentXid();

    //通过RpcContext将xid传到一个服务端

    RpcContext.getContext().setAttachment("xid", xid);

    

    //执行自己的业务逻辑

    int productId = new Random().nextInt(100);

    int productNum = new Random().nextInt(100);

    OrderDO orderDO = new OrderDO(userId, productId, productNum, new Timestamp(new Date().getTime()));

    orderService.createOrder(orderDO);

    

    //通过RpcContext将xid传到另一个服务端

    RpcContext.getContext().setAttachment("xid",xid);

    stockService.updateStock(orderDO);

}

public int updateStock(OrderDO orderDO) {

//获取全局事务ID,并绑定到上下文

String xid = RpcContext.getContext().getAttachment("xid");

TxcContext.bind(xid,null);

//执行自己的业务逻辑

int ret = jdbcTemplate.update("update stock set amount = amount - ? where product_id = ?",new Object[]{orderDO.getNumber(), orderDO.getProductId()});

TxcContext.unbind();

return ret;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

纵然间

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

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

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

打赏作者

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

抵扣说明:

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

余额充值