Share:
阿里的分布式事务框架seata, 文章
分布式事务的理论基础 : 2PC。 简单来说,一个分布式事务包含两个阶段 : 第一个阶段是prepare, 当所有资源都prepare 成功,才会执行第二个阶段 : commit。
这里我补充一下个人的理解:
- 为什么需要prepare ? 这其实是跟成功率有关,通常大部分的事务都会在第一个访问资源就失败,反过来说,第一个阶段成功,第二个阶段会失败的可能性就会相对低很多。
- 所有事务都需要提前考虑好回滚的操作,就像DB 的回滚就是恢复数据,但这只是一种针对db 的场景,这也是一种最基础的场景。不是所有场景都可以支持数据的恢复,所以要使用分布式协议的时候必须先考虑自己的业务场景是否可以支持回滚。
TCC, TCC 的底层理论就是2PC,TCC 可以简单理解成服务器的2PC 实现抽象,将2PC 抽象成以下几个操作 : Try - Commit - Cancel.
Try 相当于Prepare, Commit 相当于 提交, Cancel 对应的就是回滚。
Seata 实现了TCC 协议, 他的实现有几个要点 :
- Try, Commit , Cancel 都要支持幂等,以应对各种网络异常, 文章介绍了防悬挂,可重复的实现原理,其中的核心思想就是幂等。
- 引入无锁设计,尽量做到高吞吐量
针对不同的分布式场景 Seata 实现了以下几种模式:
- AT 模式, 最传统的模式,不同的数据库实例之间支持分布式事务,对业务代码无入侵。
- TCC 模式, 仍然需要数据库支持,但需要业务去 TCC协议,可以做到无锁设计,但对业务代码有侵入
- XA模式, 底层是event 和状态机跳转, 不需要DB 支持, 只需要业务自己编排流程和正反向action,吞吐量高, 但实现不了隔离性。 XA 模式其实是比较适合现在的互联网长事务场景,因为有些DB 资源属于外部系统,无法对其进行事务隔离。
Review:
4中技巧令到Java 程序变得更好, 这篇文章其实就是使用Interface 的泛型组合,可以避免为不同的组合创建不同的实现类
package com.tencent.travel.dispatchorder.controller;
import java.util.List;
public class ReaderPrinterComposite<T extends Reader & Printer> implements Reader,Printer {
private List<T> readerPrinters;
public ReaderPrinterComposite(List<T> readerPrinters)
{
this.readerPrinters = readerPrinters;
}
@Override
public void print()
{
for (Printer printer: this.readerPrinters)
{
printer.print();
}
}
@Override
public void read()
{
for (Reader reader: this.readerPrinters)
{
reader.read();
}
}
}
Tips:
这周我体验了不同的架构图画图工具,就自己的使用体验而言,PlantUML 还是最顺手,因为用文本有以下好处:
- 更容易做版本管理和分享
- 相对于图形工具,文本工具能更让人集中于流程而不是画图的细节
Algorithm: