支付宝分布式事务介绍
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
} return (Integer) transactionTemplate.execute(new TransactionCallback() { public Object doInTransaction(TransactionStatus status) {
logger.error("严重异常:参数不全;尝试解释业务活动状态[businessType=" + businessType + ";businessId="+ businessId + "]时。"); return BusinessActivityStateResolver.UNKNOWN;
if (StringUtil.equals(WithdrawBusinessType.BALANCE, businessType)) { try { WithdrawInstructionDO data = withdrawInstructionDAO.lock(businessId); if (data == null) {
事务管理器 TM 2. 4.
提 交
准 备
提 交
资源管理器 RM1
事务管理器 TM
资源管理器 RM2
回 滚
准 备
回 滚
资源管理器 RM1
21:31
资源管理器 RM2
准备操作与ACID • A: 准备后,仍可提交与回滚 • C: 准备时,一致性检查必须OK • I: 准备后,事务结果仍然只在 事务内可见 • D: 准备后,事务结果已经持久 局限 • 协议成本 (准备操作是一定必须 的吗) • 准备阶段的持久成本 • 全局事务状态的持久成本 • 潜在故障点多带来的脆弱性 • 准备后,提交前的故障引发一 系列隔离与恢复难题
/ /
21:31
AP
日志 锁
完成会话
复 习
全局事务(DTP模型)
全局事务 事务由全局事务管理 器全局管理 事务管理器 管理全局事务状态与 参与的资源,协同资 源的一致提交/回滚 TX协议 应用或应用服务器与 事务管理器的接口 XA协议 全局事务管理器与资 源管理器的接口
5 5
应用/应用框架/应用服务器 AP 开 始 全 局 事 务 1.
21:31
持久操作3
提交/回滚本地事务 提交/回滚本地事务
9
回 顾
bankgw
账务服务化
确保通知
trade
acctrans
持久操作1 持久操作2 持久操作3
主 库
提交/回滚分布事务
账 务 库
持久操作4
提交/回滚分布事务
21:31 10
回 顾
mipgw
双峰插云
paycore acctrans
持久操作3
持久操作2
持久操作1
主 库
支 付 库 提交/回滚嵌套分布事务
账 务 库
21:31
11
集 成
适用场景
基本原则
业务活动中包括账务参与者的 只要操作账务,必须使用分布式事务,支付宝系统特有 账务是作为默认参与者存在的 多个业务活动参与者之间必须保持语义状态一致性的 可选,对于非实时类业务,可使用高可靠的ESB消息完成一致性
支付宝分布式事务介绍
2009年7月27日 核心开发组红雪
21:31 1
大
纲
What- 分布事务快速浏览
Why- 为什么要引入分布事务
How- 如何实现分布事务 Warning- 注意点
21:31
2
复 习
事务3 事务2 事务1
事
务
事务:
由一组操作构成的可靠、 独立的工作单元
ACID:
C4
C 资 源B 位 置 A A1
账务处理逻辑
持久操作2 持久操作1 持久操作3 持久操作4
主 库 提交/回滚本地事务
21:31
提交/回滚本地事务
8
回 顾 bankgw
网银处理逻辑
交易服务化进程 trade
通 知
账务处理逻辑
交易处理逻辑
源自文库
持久操作2 持久操作1 持久操作4
iwallet
账务处理逻辑 持久操作4
主 库 提交/回滚本地事务
C2 B3
• • • •
Atomicity(原子性) Consistency(一致性) Isolation(隔离性) Durability(持久性)
难点:
A5
• 高度并发 • 资源分布 • 大时间跨度
1
2
3 4 操作时间
5
21:31
3
复 习
开始会话 应 用 应 用 服 务 器 应 用 框 架
本地事务
本地事务 事务由资源管理器(如 DBMS)本地管理 优点 • 支持严格的ACID属性 • 可靠 • 高效 • 状态可以只在资源管理器 中维护 • 应用编程模型简单(在框 架或平台的支持) 局限 • 不具备分布事务处理能力 • 隔离的最小单位由资源管 理器决定,如数据库中的 一条记录
4
开始事务
操作1 … 操作n 提交/回滚事务 资 源 管 理 器 RM
遵守
必须在本地事务块中开启分布式事务; 必须使用全局唯一的主事务号
21:31
12
集 成
业务系统开启本地事务块;
工作原理及步骤
启动一个业务活动;事务同步器持久化此业务活动记录至DB,并将主事务号存放至本地线 程变量中; 业务系统开始调用账务服务:账务的服务接口参数列表的txId主事务号是无需设置的,事 务同步器会用本地线程变量内的主事务号替换之; 账务前置进行账务处理后同步响应处理结果; 业务系统分析账务处理结果,如正常则提交本地事务块;事务同步器调用账务交易结束器 完成账务提交,如账务提交失败则后续等待分布式事务恢复查询继续尝试提交,直至账务提 交完成为止; 若本地事务回滚,同步器则调用账务交易结束器完成账务回滚,如账务回滚失败则后续等 待分布式事务恢复程序继续尝试回滚,直至账务回滚成功为止。
6
OK OK
OK
OK
OK OK
4.
2.
3.
NO
OK
6
回 顾
网关未独立前:一条龙
iwallet
网银处理逻辑 账务处理逻辑 交易处理逻辑
持久操作1
持久操作2
持久操作3
持久操作4
主 库
提交/回滚本地事务
21:31 7 7
回 顾 bankgw
网银处理逻辑 账务处理逻辑
网关独立部署 iwallet
通 知
交易处理逻辑
21:31
14
集 成
本地事务模板
transactionTemplate ① 使用主库dataSource:在本地事务提交 /回滚发生时,主事务记录(处于主库)的提 交/回滚状态可做到确保一致;当事务同步 器无法顺利提交/回滚账务操作,则分布式 任务恢复程序在进行恢复时无需回查业务 当前状态
使用非主库dataSource:在本地事务提 交/回滚发生时,主事务记录(处于主库)的 提交/回滚状态无法做到确保一致;当事务 同步器无法顺利提交/回滚账务操作,则分 布式任务恢复程序在进行恢复时需要回查 业务当前状态
21:31
13
集 成
示例代码
public AccountTransResult foo() { return (AccountTransResult)transactionTemplate ①.execute(new TransactionCallback() { //确保在本地事务块中 public Object doInTransaction(TransactionStatus status) { AccountTransResult transResult =null; try { businessActivityControlService.start(...); ② //启动业务活动 transResult = accountTransFacade.freezeAccountBalance(null,...); //请求账务交易处理 //判断账务前置处理结果 if (transResult.isSuccess()) { localBizHandle(); //本地业务逻辑处理 localDBHandle(); //本地数据持久处理 } else {
21:31
15
集 成
回查实现示例代码
/* (non-Javadoc) * @see com.alipay.sofa.platform.xts.bacs.spi.BusinessActivityStateResolver#isDone(java.lang.String, java.lang.String) */ public int isDone(String businessType, String businessId) { if (StringUtil.isBlank(businessType) || StringUtil.isBlank(businessId)) {
logger.error("严重异常:支付指令数据不存在;尝试解释业务活动状态[businessType=" + businessType+ ";businessId=" + businessId + "]时。"); return BusinessActivityStateResolver.UNKNOWN;
21:31
注 册 资 源
事务 管理器 TM
2. 1
注 册 提 资 交 源 事 务 2
4. 6.
操 作
资源 管理器 RM1
3. 1..n
操 作
资源 管理器 RM2
5. 1..n
7. 准备
8. 准备 9. 提交 10. 提交
复 习
1. 准 备 准 备 1. 3.
两阶段提交(Two Phase Commit)
logger.error(...);
} } catch (Exception e) { logger.error(...);
、 status.setRollbackOnly(); //显式回滚
}
});
}
status.setRollbackOnly(); //显式回滚 } return transResult;
}
});
}
} else if (StringUtil.equals(InstructionStatusEnum.PRE_ACCREDITED.getCode(), data.getStatus())) { logger.warn("成功解释业务活动状态[businessType=" + businessType + ";businessId="+ businessId + "]:未执行。"); return BusinessActivityStateResolver.NOT_DONE; } else if (StringUtil.equals(InstructionStatusEnum.SUBMIT_SETTLED.getCode(), data.getStatus())) { logger.warn("成功解释业务活动状态[businessType=" + businessType + ";businessId="+ businessId + "]:已执行。"); return BusinessActivityStateResolver.DONE; }else { logger.error("严重异常:支付指令数据状态不正常,当前状态:" + data.getStatus() + ";尝试解释业务活动状态[businessType=" + businessType+ "; businessId=" + businessId + "]时。"); return BusinessActivityStateResolver.UNKNOWN; } } catch (Exception e) { logger.warn("警告:数据库异常;尝试解释业务活动状态[businessType=" + businessType+ ";businessId=" + businessId + "]时。", e); return BusinessActivityStateResolver.UNKNOWN; } }else { logger.error("严重异常:无需进行业务活动解释的类型;尝试解释业务活动状态[businessType=" + businessType+ ";businessId=" + businessId + "]时。"); return BusinessActivityStateResolver.UNKNOWN; }
21:31
16
集 成
启动业务活动
businessActivityControlService.start(...); ②
业务活动的启动有两种方式: 带参数: businessType + businessId businessType:业务活动类别,每个类别的前 三位对应到某个业务类型,后三位是对此业务类 型的具体操作;如002代表提现,而002001代表 提现申请中的冻结部分 businessId:业务数据的ID或可以唯一定位到 业务数据的key 无参数:系统自动分配业务活动ID(全局唯一) 推荐使用以businessType + businessId方式启动业 务活动: 根据businessType 可准确定位至业务及操作,便利 了对故障的分析、排查、以及出错系统的快速定位 利用businessType的前三位,分布式任务恢复程序 可以找到正确的回查实现者 通过businessId,可以迅速的定位到具体的业务数 据、日志信息等