首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

最大努力型事务

有内涵、有价值的文章第一时间送达!

BASE Transaction

Best efforts delivery transaction (已经实现).

Try confirm cancel transaction (待定).

Sharding-JDBC由于性能方面的考量,决定不支持强一致性分布式事务。

最大努力送达型事务

在分布式数据库的场景下,相信对于该数据库的操作最终一定可以成功,所以通过最大努力反复尝试送达操作。

最大努力送达型事务的架构图

最大努力送达型事务的架构图

摘自sharding-jdbc使用指南☞事务支持

执行过程有以下几种情况:

执行成功--如图所示,执行结果事件->监听执行事件->执行成功->清理事务日志

执行失败,同步重试成功--如图所示,执行结果事件->监听执行事件->执行失败->重试执行->执行成功->清理事务日志

执行失败,同步重试失败,异步重试成功--如图所示,执行结果事件->监听执行事件->执行失败->重试执行->执行失败->"异步送达作业"重试执行->执行成功->清理事务日志

执行失败,同步重试失败,异步重试失败,事务日志保留----如图所示,执行结果事件->监听执行事件->执行失败->重试执行->执行失败->"异步送达作业"重试执行->执行失败->... ...

说明:不管执行结果如何,执行前事件都会记录事务日志;执行事件类型包括3种:BEFOREEXECUTEEXECUTEFAILUREEXECUTESUCCESS;另外,这里的"同步"不是绝对的同步执行,而是通过google-guava的EventBus发布事件后,在监听端判断是EXECUTEFAILURE事件,最多重试 次;后面对 的源码分析有介绍;这里的"异步"通过外挂实现,在后面的文章10. sharding-jdbc源码之异步送达JOB会有分析;

适用场景

根据主键删除数据。

更新记录永久状态,如更新通知送达状态。

使用限制

使用最大努力送达型柔性事务的SQL需要满足幂等性。

INSERT语句要求必须包含主键,且不能是自增主键。

UPDATE语句要求幂等,不能是UPDATE xxx SET x=x+1

DELETE语句无要求。

开发示例

备注:SoftTransactionConfiguration支持的配置以及含义请参考sharding-jdbc使用指南☞事务支持,这段开发示例的代码也摘自这里;也可参考 模块中 如何使用柔性事务,但是这里的代码需要稍作修改,否则只是普通的执行逻辑,不是sharding-jdbc的执行逻辑

核心源码分析

通过3. sharding-jdbc源码之路由&执行中对ExecutorEngine的分析可知,sharding-jdbc在执行SQL前后,分别调用 提交了事件,那么调用 的地方,就是柔性事务处理的地方,通过查看源码的调用关系可知,只有 调用了 ,所以柔性事务实现的核心在SoftTransactionManager这里;

柔性事务管理器

柔性事务实现在 中,核心源码如下:

从这段源码可知,柔性事务的几个重点如下,接下来一一根据源码进行分析;

事务日志存储器;

最大努力送达型事务监听器;

异步送达JOB任务;

1.事务日志存储器

柔性事务日志接口类为 ,有两个实现类:

RdbTransactionLogStorage:关系型数据库存储柔性事务日志;

MemoryTransactionLogStorage:内存存储柔性事务日志;

1.1.1事务日志核心接口

TransactionLogStorage中几个重要接口在两个实现类中的实现:

void add(TransactionLog):Rdb实现就是把事务日志TransactionLog 插入到表中,Memory实现就是把事务日志保存到中;

void remove(String id):Rdb实现就是从表中删除事务日志,Memory实现从中删除事务日志;

void increaseAsyncDeliveryTryTimes(String id):异步增加送达重试次数,即TransactionLog中的asyncDeliveryTryTimes+1;Rdb实现就是update表中字段加1;Memory实现就是TransactionLog中重新给asyncDeliveryTryTimes赋值;

findEligibleTransactionLogs(): 查询需要处理的事务日志,条件是:①,②,③,每次最多查询参数size条;Rdb实现通过sql从transaction_log表中查询,Memory实现遍历ConcurrentHashMap匹配符合条件的TransactionLog;

boolean processData():Rdb实现执行TransactionLog中的sql,如果执行过程中抛出异常,那么调用increaseAsyncDeliveryTryTimes()增加送达重试次数并抛出异常,如果执行成功,删除事务日志,并返回true;Memory实现直接返回false(因为processData()的目的是执行TransactionLog中的sql,而Memory类型无法触及数据库,所以返回false)

1.1.2事务日志存储核心源码

实现源码:

1.1.3事务日志存储样例

transaction_log中存储的事务日志样例:

1.2最大努力送达型事务监听器

核心源码如下:

BestEffortsDeliveryListener源码总结:

执行前,插入事务日志;

执行成功,则删除事务日志;

执行失败,则最大努力尝试次;

1.3 异步送达JOB任务

部署用于存储事务日志的数据库。

部署用于异步作业使用的zookeeper。

配置YAML文件,参照示例文件config.yaml。

下载并解压文件sharding-jdbc-transaction-async-job-$VERSION.tar,通过start.sh脚本启动异步作业。

异步送达JOB任务基于elastic-job,所以需要部署zookeeper;

END

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180611G1L2S600?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券