一,分布式事务传播行为

调用链描述

一个普通事务注解的方法,调用一个分布式事务注解方法

分布式事务注解方法:包含一个本地更新,和两个外部服务更新操作,涉及三个服务

问题

1,普通事务注解方法,在全局事务问题中,是否会生效回滚@答案是会回滚

原因

1,分布式事务注解,抽离到另外一个类中,不会出现AOP失效的问题

2. 事务传播机制
FulfillOrderBizService.userCancel 使用 @Transactional 创建本地事务
当调用 OutboundSellOrderBizService.userCancel 时,由于是通过代理对象调用,@GlobalTransactional 能够正常工作
Seata的分布式事务会接管整个事务管理,包括之前由 @Transactional 开启的本地事务
3. Seata的工作机制
Seata的 @GlobalTransactional 注解具有以下特点:
一旦开启全局事务,会覆盖本地事务管理器
能够管理跨服务的事务操作
在调用链中传播全局事务上下文

代码

@Transactional(rollbackFor = Exception.class)
@XLock(prefix = "OUT_BOUND_SELL_ORDER_USER_CANCEL", keys = {"#orderNo"}, leaseTime = 5L, waitTime = 5L)
public void userCancel(String orderNo) {
@GlobalTransactional(rollbackFor = Exception.class)
public void userCancel(OutboundSellOrderCancelParam param) {
 @Transactional(rollbackFor = Exception.class)@XLock(prefix = "OUT_BOUND_SELL_ORDER_USER_CANCEL", keys = {"#orderNo"}, leaseTime = 5L, waitTime = 5L)public void userCancel(String orderNo) {// 更新本地1fulfillOrderService.updateById(new FulfillOrderParam().setId(fulfillOrderBO.getId()).setStatus(FulfillOrderStatusEnum.CANCELED.getCode()));// 调用分布式事务注解方法outboundSellOrderBizService.userCancel(cancelParam);}@GlobalTransactional(rollbackFor = Exception.class)public void userCancel(OutboundSellOrderCancelParam param) {// 更新本地2,抽离到另外一个类,不需要加注解OutboundOrder outboundOrder = outboundOperateService.userCancel(param);// 更新远程服务 取消配送和取货服务cancelDeliveryAndReceiveOrder("C端用户取消", param, outboundOrder);}/*** 取消配送和取货服务*/private void cancelDeliveryAndReceiveOrder(String operator, OutboundSellOrderCancelParam param, OutboundOrder outboundOrder) {// 更新取货服务boolean cancelResult = receiveOrderService.cancelOrder(new OrderParam().setOutOrderCode(outCode).setOperationUser(param.getOperationUser()).setOperationEnterprise(param.getOperationEnterprise()));// 更新配送服务CancelDeliveryBO cancelDeliveryBO = deliveryService.cancel(new CancelDeliveryParam().setLogisticsNo(outboundOrder.getLogisticsNo()).setCancelTime(new Date()));}// 更新本地2,抽离到另外一个类,不需要加注解@Overridepublic OutboundOrder userCancel(BaseOutboundOpParam param) {

疑问及测试说明

* todo 分布式事务问题
* order 是否需要回滚
* 取消出库单失败,回滚
* 取消配送,是否回滚 @回滚
* FulfillOrderBizService.userCancel 方法中的本地事务会覆盖掉 OutboundSellOrderBizService.userCancel 方法的分布式事务特性
* @实际不会覆盖。应该配送失败,取货是否回滚,判断分布式事务 @回滚
*/

二,內部调用导致事务失效解决

需求描述

批量取消配送单,可部分成功,部分失败。

调用链:wms 分别调用配送中心,取货中心

实现目标

可以实现独立事务

可以实现分布式事务

代码

public List<OutboundSellOrderCancelVO> cancel(OutboundSellOrderCancelForm form) {List<OutboundSellOrderCancelVO> results = new ArrayList<>();for (String outCode : form.getOutCodes()) {try {// 每个订单独立事务处理OutboundSellOrderCancelVO result = self.processSingleOrderInTransaction(outCode, form);results.add(result);} catch (Exception e) {log.error("取消分配 失败, 出库单号: {}, 错误信息: {}", outCode, e.getMessage(), e);OutboundSellOrderCancelVO failureVO = new OutboundSellOrderCancelVO();failureVO.setOutCode(outCode);failureVO.setErrorMessage(e.getMessage());results.add(failureVO);}}log.info("取消分配 完成,总数: {}, 成功: {}, 失败: {}",form.getOutCodes().size(),results.stream().filter(vo -> StringUtils.isBlank(vo.getErrorMessage())).count(),results.stream().filter(vo -> StringUtils.isNotBlank(vo.getErrorMessage())).count());return results;}/*** 每个订单独立事务处理*/@GlobalTransactional(rollbackFor = Exception.class)public OutboundSellOrderCancelVO processSingleOrderInTransaction(String outCode, OutboundSellOrderCancelForm form) {OutboundSellOrderCancelParam param = new OutboundSellOrderCancelParam();param.setOutCode(outCode);param.setOperationUser(form.getOperationUser());param.setOperationEnterprise(form.getOperationEnterprise());// 1. 取消销售出库单OutboundOrder outboundOrder = outboundOperateService.cancelDelivery(param);param.setExternalCode(outboundOrder.getExternalCode());// 2. 取消配送单、取货单cancelDeliveryAndReceiveOrder("B端取消", param, outboundOrder);// 返回成功结果return new OutboundSellOrderCancelVO().setOutCode(outboundOrder.getOutCode());}

疑问及测试说明

/*** 事务生效问题* processSingleOrderInTransaction self* self @回滚* not self @不回滚** 事务传播问题* self 前提下,删除outboundService.cancelDelivery 事务注解* @当 outboundService.cancelDelivery 方法没有 @Transactional 注解,但被一个已有事务的方法调用时,它会加入当前事务。** 事务独立问题* self 前提下,一个成功,一个失败,失败会回滚** 分布式事务问题* 配送失败,回滚,出库单,取货单* @生效*/

解决方法

通过self实现自调用

OutboundSellOrderCancelVO result = self.processSingleOrderInTransaction(outCode, form);

类实现自注入接口,在类中注入它自己

public class OutboundSellOrderBizService implements BeanSelfAware {
private OutboundSellOrderBizService self;
@Override
public void setSelf(Object proxyBean) {self = (OutboundSellOrderBizService) proxyBean;
}
/*** spring 自身注入自身方法 , 解决内部方法调用不走代理的问题.** @author Luo* @date 2021-9-23 10:59:37*/
public interface BeanSelfAware {/*** 注入自身对象.** @param proxyBean 代理bean*/void setSelf(Object proxyBean);
}

实现原理

总结:要通过代理对象调用,怎么获取代理对象

工作原理
Spring容器初始化:当Spring容器创建OutboundSellOrderBizService bean时,会创建一个代理对象(如果存在AOP切面)
回调注入:Spring通过BeanSelfAware接口的setSelf方法,将代理对象注入到self字段中

疑问

1,代理对象什么实现创建的

2,具体如何将代理对象注入到self字段中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/95737.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/95737.shtml
英文地址,请注明出处:http://en.pswp.cn/web/95737.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

美团龙猫利用expat库实现的保存xml指定范围数据到csv的C程序

用自己代码逐个字符解析的速度较慢&#xff0c;尝试了libxml2也比较慢&#xff0c;它需要一次性读入内存&#xff0c;而expat库支持流式读取。就让龙猫写了一个程序&#xff0c;毕竟是久经考验的库&#xff0c;程序很快就调试通过了。要不是我一开始没信心&#xff0c;让他先输…

Transformer核心—自注意力机制

Transformer基础—自注意力机制 当我们处理文本、语音这类序列数据时&#xff0c;总会遇到一个老问题&#xff1a;模型到底该怎么理解“前后文”呢&#xff1f; RNN 和 LSTM 曾经是热门的答案&#xff0c;它们沿着时间顺序一点点地读数据&#xff0c;但读得太慢&#xff0c;还容…

分片上传-

分片上传原理&#xff1a;客户端将选择的文件进行切分&#xff0c;每一个分片都单独发送请求到服务端&#xff1b;断点续传 & 秒传原理&#xff1a;客户端 发送请求询问服务端某文件的上传状态 &#xff0c;服务端响应该文件已上传分片&#xff0c;客户端再将未上传分片上传…

零知开源——基于STM32F103RBT6的智能风扇控制系统设计与实现

✔零知IDE 是一个真正属于国人自己的开源软件平台&#xff0c;在开发效率上超越了Arduino平台并且更加容易上手&#xff0c;大大降低了开发难度。零知开源在软件方面提供了完整的学习教程和丰富示例代码&#xff0c;让不懂程序的工程师也能非常轻而易举的搭建电路来创作产品&am…

ReACT Agent概述

目录 1. 核心思想&#xff1a;解决传统方法的局限性 2. ReACT 的工作原理&#xff1a;一个循环过程 3. 技术实现的关键要素 4. ReACTAgent 在任务中的具体工作流程 5. 优势与重要性 6. 挑战与局限性 总结 ReACT 是一个非常重要的框架&#xff0c;它代表了构建能够推理&a…

必知!机器人的分类与应用:RPA、人形与工业机器人

每当提及“机器人”这三个字&#xff0c;许多人的第一反应或许仍是科幻电影中那种具备人类外形、可自由行走与对话的仿生装置。然而&#xff0c;一个值得深入探讨的科技现实是&#xff1a;我们对于人形机器人的迷恋&#xff0c;更多源自文化叙事与情感投射&#xff0c;而非真实…

最快的 C 语言 JSON 库 - yyjson

文章目录DOM 模式下的性能比对一、AWS EC2 (AMD EPYC 7R32, gcc 9.3)二、iPhone (Apple A14, clang 12)持续更新中 持续更新中 持续更新中一个用 ANSI C(C89) 编写的高性能 JSON 库 API.md DOM 模式下的性能比对 DOM 模式&#xff0c;即构建完整 JSON 内存结构后访问数据的模…

TP8 模型save更新不成功

一、User文件头部代码class User extends Model {const TITLE_NAME 用户;//名称//不能删除protected $name user_; //表名 protected $connection \app\services\database\model\DbConnModel::CONN_DB_SITE; //数据库的连接二、更新部分我要更新user_1用户表中的用户信息$se…

中囯移动电视盒子(魔百和)B860AV2.1-A2和CM311-5-zg刷机手记

文章目录B860AV2.1-A2电视盒子情况打开隐藏或屏蔽的功能进入Recovery模式打开WiFi&#xff08;如果被隐藏&#xff09;打开运维调试打开ADB调试安装第三方应用、设置第三方桌面等&#xff08;Fiddler抓包替换官方App安装包&#xff09;开启ADB和使用ADB禁止“首次启动设置”刷机…

【系统架构设计(14)】项目管理下:软件质量与配置管理:构建可靠软件的基础保障

文章目录一、核心思想二、软件质量属性&#xff1a;定义"好软件"的标准三、质量保证与控制&#xff1a;实现质量标准的方法四、CMMI模型&#xff1a;组织质量能力的演进路径五、软件配置管理&#xff1a;质量成果的保护机制六、软件工具&#xff1a;质量管理的技术支…

码农的“必修课”:深度解析Rust的所有权系统(与C++内存模型对比)

在软件开发的世界里&#xff0c;内存管理是至关重要的一个环节。它是程序运行的基础&#xff0c;直接关系到程序的性能、稳定性和安全性。一个糟糕的内存管理策略&#xff0c;可能导致内存泄漏、野指针、缓冲区溢出等一系列令人头疼的问题&#xff0c;甚至带来灾难性的安全漏洞…

Java全栈学习笔记30

# MySQL 卸载安装版电脑管家/360/控制面板卸载mysql服务即可删除ProgramData中的MySQL目录解压版winr 输入 services.msc 打开服务管理。查看是否存在MySQL&#xff0c;如果存在则删除注册表 winR regedit 打开注册表计算机\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Servic…

Transformers 学习入门:前置知识补漏

在学习 Transformers 之前&#xff0c;打好神经网络和自然语言处理的基础至关重要。本文整理了需要掌握的核心前置知识&#xff0c;用通俗的例子帮你快速理解复杂概念&#xff0c;为后续学习铺平道路。​ 一、神经网络基础​ 1. 多层感知机&#xff08;MLP&#xff09;&#xf…

双摄工业相机的主要特点和应用场景

双摄工业相机&#xff08;双目摄像头&#xff09;在工业领域中的应用非常广泛&#xff0c;其核心优势在于通过双镜头模拟人眼立体视觉&#xff0c;能够获取深度信息并实现高精度三维重建。 一、双摄工业相机的核心优势 深度感知与三维重建 双目摄像头通过两个镜头从不同角度拍…

YOLOv11改进:FocalModulation替换SPPF(精度更高的空间金字塔池化)

YOLOv11&#xff1a;FocalModulation替换SPPF&#xff08;精度更高的空间金字塔池化&#xff09; 引言 在目标检测领域&#xff0c;YOLO系列算法以其高效性和准确性广受欢迎。作为YOLO系列的最新成员之一&#xff0c;YOLOv11在多个方面进行了优化和改进。其中&#xff0c;空间金…

LLM与数据工程的融合:衡石Data Agent的语义层与Agent框架设计

在数字经济浪潮中&#xff0c;企业数据智能正经历从"工具辅助"到"智能协同"的范式跃迁。传统BI系统受限于静态报表与预设指标&#xff0c;难以应对动态业务场景的复杂需求。衡石科技发布的HENGSHI SENSE 6.0通过"Data AI Agent"架构创新&#x…

假设一个算术表达式中包含圆括号、方括号和花括号3种类型的括号,编写一个算法来判别,表达式中的括号是否配对,以字符“\0“作为算术表达式的结束符

思想:这道题是栈的应用类型&#xff0c;我们可以建立一个栈来保存(,[,{,通过遍历字符串如果是三个左括号其中一个则入栈&#xff0c;当遇到)]}则出栈配对&#xff0c;如果左右匹配&#xff0c;则遍历下一个元素&#xff0c;如果不匹配直接返回&#xff0c;如果遍历字符串结束&a…

鸿蒙Next的UI国际化与无障碍适老化实践:构建全球包容的数字世界

科技不应让任何人掉队&#xff0c;鸿蒙Next正将这一理念变为现实在全球化日益深入的今天&#xff0c;应用的国际化与无障碍设计不再是"锦上添花"&#xff0c;而是不可或缺的核心竞争力。华为鸿蒙Next系统从设计之初就深入考虑了这些需求&#xff0c;为开发者提供了完…

深度学习——迁移学习

迁移学习作为深度学习领域的一项革命性技术&#xff0c;正在重塑我们构建和部署AI模型的方式。本文将带您深入探索迁移学习的核心原理、详细实施步骤以及实际应用中的关键技巧&#xff0c;帮助您全面掌握这一强大工具。迁移学习的本质与价值迁移学习的核心思想是"站在巨人…

RAG|| LangChain || LlamaIndex || RAGflow

大模型&#xff1a;预训练模型 外挂知识库&#xff1a;知识库->向量数据库 输入-》预处理成向量 提示词-》llm归纳总结 离线&#xff1a;企业原文本存到向量数据库 向量&#xff1a; 同一个向量模型&#xff08;第二代检索&#xff0c;推荐&#xff0c;个人助理&#xff0c;…