分布式事务TCC实现框架——Hmily

分布式事务

1. TCC事务概述

TCC(Try/Confirm/Cancel)编程模式的核心思想是:针对每个分支事务操作,都要向全局事务发起方注
册Try、Confirm和Cancel三个操作,具体这些操作由我们自己根据业务进行实现,然后分为两个阶段去
执行:

  1. Try 阶段主要是做业务检查(一致性)及资源预留(隔离),此阶段仅是一个初步操作,它和后续的
    Confirm 一起才能真正构成一个完整的业务逻辑。
  2. Confirm 阶段主要是做确认提交,Try阶段所有分支事务执行成功后开始执行 Confirm。通常情况
    下,采用TCC则认为 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。若
    Confirm阶段真的出错了,需引入重试机制或人工处理。
  3. Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行分支事务的业务取消,预留资源释
    放。通常情况下,采用TCC则认为Cancel阶段也是一定成功的。若Cancel阶段真的出错了,需引入重试机制或人工处理。
    在这里插入图片描述
    案例1: A转账30元给B,A账户和B账户在不同银行(服务),当前余额都为100元
    在这里插入图片描述
    我们需要把之前实现的转账的代码拆分成三块,套到try-confirm-cancel中,由事务管理器(协调管理)推进AB两个try分别执行,在这个过程中,事务管理器会对AB进行监控,一旦任何一方出现了问题,就推进对方执行cancel;如果双方都没有异常,就推进AB执行confirm。如果在执行confirm或cancel过程中出现问题,就引入重试机制或由人工处理。
    TCC解决方案要求每个分支事务实现三个操作Try/Confirm/Cancel。try操作做业务检查及资源预留,Confirm操作做业务确认操作,Cancel操作需要实现一个与try相反的操作。TM(事务管理器)首先发起所有的分支事务的try操作,任何一个分支事务的try操作执行失败,TM将会发起所有分支事务的Cancel操作,若try操作全部成功,TM将会发起所有分支事务的Confirm操作,其中Confirm/Cancel操作若执行失败,TM会进行重试,因此需要实现幂等。
    Try/Confirm/Cancel这三个操作的具体实现,由开发者根据业务情况灵活掌握。
    TCC不足之处:
    对应用的侵入性强。业务逻辑的每个分支都需要实现try、confirm、cancel三个操作,应用侵入性较强,改造成本高。
    实现难度较大。需要按照网络状态、系统故障等不同的失败原因实现不同的回滚策略。为了满足一致性的要求,confirm和cancel接口必须实现幂等。

2.Hmily框架

yml配置

org:
	dromara:
		hmily :
			serializer : kryo #序列化工具
			retryMax : 30 #最大重试次数
			repositorySupport : db #持久化方式
			started: true #事务发起方
			hmilyDbConfig :
				driverClassName : com.mysql.jdbc.Driver
				url : jdbc:mysql://localhost:3306/bank1?useUnicode=true
				username : root
				password : 123

配置类

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass=true)//springboot可省略
public class DatabaseConfiguration {
@Autowired
private Environment env;
@Bean
public HmilyTransactionBootstrap hmilyTransactionBootstrap(HmilyInitService
hmilyInitService){
HmilyTransactionBootstrap hmilyTransactionBootstrap = new
HmilyTransactionBootstrap(hmilyInitService);
hmilyTransactionBootstrap.setSerializer(env.getProperty("org.dromara.hmily.seri
alizer"));
hmilyTransactionBootstrap.setRetryMax(Integer.parseInt(env.getProperty("org.dro
mara.hmily.retryMax")));
hmilyTransactionBootstrap.setRepositorySupport(env.getProperty("org.dromara.hmi
ly.repositorySupport"));
hmilyTransactionBootstrap.setStarted(Boolean.parseBoolean(env.getProperty("org.
dromara.hmily.started")));
HmilyDbConfig hmilyDbConfig = new HmilyDbConfig();
hmilyDbConfig.setDriverClassName(env.getProperty("org.dromara.hmily.hmilyDbConf
ig.driverClassName"));
hmilyDbConfig.setUrl(env.getProperty("org.dromara.hmily.hmilyDbConfig.url"));
hmilyDbConfig.setUsername(env.getProperty("org.dromara.hmily.hmilyDbConfig.user
name"));
hmilyDbConfig.setPassword(env.getProperty("org.dromara.hmily.hmilyDbConfig.pass
word"));
hmilyTransactionBootstrap.setHmilyDbConfig(hmilyDbConfig);
return hmilyTransactionBootstrap;
}
}

**在需要分布式事务的调用方接口方法上加上@Hmily

@FeignClient(value = "hmily-demo-bank2")
public interface Bank2Client {
@GetMapping("/bank2/transfer")
@Hmily
Boolean transfer(@RequestParam("amount") Double amount);
}

启动类上加上扫描包org.dromara.hmily

@SpringBootApplication(exclude = MongoAutoConfiguration.class)
@EnableDiscoveryClient
@EnableFeignClients(basePackages =
{"cn.itcast.wanxintx.hmilydemo.bank1.feignClient"})
@ComponentScan({"cn.itcast.wanxintx.hmilydemo.bank1","org.dromara.hmily"})
public class Bank1HmilyServer {
public static void main(String[] args) {
SpringApplication.run(Bank1HmilyServer.class, args);
}
}

3.注册功能中的分布式事务流程

在这里插入图片描述用户向用户中心发起注册请求,用户中心保存用户业务信息,然后远程调用统一账号服务保存该用户所
对应的账号信息,该业务存在分布式事务问题。
针对注册业务,如果用户与账号信息不一致,则会导致严重问题,因此该业务对一致性要求较为严格,
且属于执行时间较短的业务。TCC方案的软状态时间很短,一致性较强,因此在此业务,我们选用TCC
型分布式事务解决方案。

  1. 数据库环境
    新建数据库p2p_undo_log,此库用来存储hmily事务日志,空库即可,由hmily自动建表。
  2. Maven环境
<dependency>
<groupId>org.dromara</groupId>
<artifactId>hmily-springcloud</artifactId>
<version>2.0.5-RELEASE</version>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</exclusion>
<exclusion>
<artifactId>logback-core</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<version>4.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>

学习CAP和BASE理论后得出结论:一般情况下会保证P和A,舍弃C,保证最终一致性。最终一致是指经过一段时间后,所有节点数据都将会达到一致。如订单的"支付中"状态,最终会变为“支付成功”或者"支付失败",使订单状态与实际交易结果达成一致,但需要一定时间的延迟、等待。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值