当前位置: 首页 > news >正文

一次奇怪的空指针问题分析:事务、死锁与隐式回滚

最近我们在排查一个诡异的 空指针异常,整个分析过程可以说是跌宕起伏,最终的结论也颇具隐蔽性。今天就把这个问题分享出来,希望对大家有所帮助。

问题现象

在系统中,我们有 单据 B,它通过一个 关联 ID 字段与 上级单据 A 关联。

但在某次操作中,我们发现:

  1. 单据 B 存在,并且存储了 A 的 ID
  2. 但查询 A 时,却查不到数据,导致后续代码调用 A 的 get 方法时报空指针异常

理论上,B 既然存储了 A 的 ID,A 就应该存在,否则 A 的 ID 是怎么来的?

难道 A 被删除了?
然而,代码中并没有删除 A 的逻辑,而且 DBA 查询了数据库日志,确认 A 从未被删除。那么,这就只剩下一种可能:A 从未生成

代码分析

我们回溯代码,A 和 B 是在同一个事务内生成的,具体逻辑如下:

@Transactional
public void createA() {DB生成单据A;执行业务方法C;DB生成单据B;
}

代码逻辑很简单:

  1. 第一步 生成 A。
  2. 第二步 执行 业务方法 C
  3. 第三步 生成 B,并存储 A 的 ID。

由于 B 存储了 A 的 ID,说明 DB生成单据A 代码应该成功执行了。但为什么 A 最终没有出现在数据库中?

难道是 createA() 过程中发生了异常,导致 A 没有生成?
我们查询当时的日志,发现 业务方法 C 在执行时发生了 死锁异常

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

业务方法 C 的代码如下:

@Transactional
public void doC() {try {DB生成C;} catch (Exception e) {输出异常日志;}
}

DB生成C 这一步时,数据库发生了死锁异常,但代码使用了 try-catch,所以理论上不会影响事务的执行,A 和 C 都应该正常生成。

那么问题来了,A 为什么消失了?

问题的根本原因:MySQL 隐式回滚

最终,DBA 通过查询数据库的日志,发现了问题的真正原因——MySQL 发生了“隐式回滚”

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

MySQL 死锁处理机制
在 MySQL 中,当多个事务发生死锁时,数据库会自动选择一个代价较低的事务进行回滚,以解除死锁。这一行为是 数据库层面的自动回滚不会受到 try-catch 代码的影响

在本例中,事务执行时发生了死锁,MySQL 自动回滚了整个事务 createA(),导致 A 被回滚,实际上根本没被写入数据库。

但由于 doC() 代码中使用了 try-catch,异常并没有往上抛,导致事务继续执行到了 DB生成单据B;。由于 B 在一个新的事务中生成,它最终成功入库,并存储了 已被回滚的 A 的 ID,从而导致数据不一致的问题。

完整过程如下:

  1. DB生成单据A;执行成功(暂时)
  2. DB生成C;发生死锁,MySQL 选择回滚事务 createA(),A 被回滚
  3. 由于 try-catch 捕获了异常,事务继续执行
  4. DB生成单据B;B 在新的事务中成功插入,并存储了已回滚的 A 的 ID

最终,导致 B 关联了一个不存在的 A,后续调用 A 的 get 方法时报空指针异常

如何避免类似问题?

通过这次分析,我们可以总结出几点避免类似问题的经验:

  1. 避免在事务中吞掉异常
  • try-catch 不能仅仅记录日志,如果异常影响了事务的完整性,应该显式回滚整个事务

  • 改进 doC()方法:

    @Transactional
    public void doC() {try {DB生成C;} catch (Exception e) {log.error("生成 C 失败", e);throw e; // 让事务感知异常,避免错误继续执行}
    }
  1. 尽量控制事务粒度,避免长时间持有锁
  • 业务方法 C 的执行时间过长,可能加剧死锁风险。

  • 可以考虑将 业务方法 C 放到事务外部执行,避免影响 AB 的创建:

    @Transactional
    public void createA() {DB生成单据A;DB生成单据B;
    }public void doC() {DB生成C;  // 独立事务,避免影响 A、B
    }
  1. 调整执行顺序,将c方法挪至最后

    @Transactional
    public void createA() {DB生成单据A;DB生成单据B;执行业务方法C;
    }

因为B方法的trycatch逻辑因为业务原因没法改,所以我这边采用了3的方法,并且同时优化了B方法,降低了死锁发生的概率。希望这次排查经历,能给大家一些启发!🚀🚀🚀

相关文章:

一次奇怪的空指针问题分析:事务、死锁与隐式回滚

最近我们在排查一个诡异的 空指针异常,整个分析过程可以说是跌宕起伏,最终的结论也颇具隐蔽性。今天就把这个问题分享出来,希望对大家有所帮助。 问题现象 在系统中,我们有 单据 B,它通过一个 关联 ID 字段与 上级单…...

解决aspose将Excel转成PDF中文变成方框的乱码问题

原文网址:解决aspose将Excel转成PDF中文变成方框的乱码问题_IT利刃出鞘的博客-CSDN博客 简介 本文介绍如何解决aspose将Excel转成PDF中文变成方框的乱码问题。 问题描述 用aspose将word、excel等转成PDF后,英文展示正常,但中文全部变成了…...

.net8.0使用EF连接sqlite数据库及使用Gridify实现查询的简易实现

EF Core EF Core 是一个流行的对象关系映射(ORM)框架,它简化了与数据库的交互,提供了一个高效、灵活且易于使用的数据访问层。 Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技…...

2025.2.5——五、[网鼎杯 2020 青龙组]AreUSerialz

题目来源&#xff1a;BUUCTF [网鼎杯 2020 青龙组]AreUSerialz 一、打开靶机&#xff0c;整理信息 直接得到一串php代码&#xff0c;根据题目可以看到还有序列化 二、解题思路 step 1&#xff1a;代码审计 <?phpinclude("flag.php");highlight_file(__FILE__…...

电风扇各国检测认证详细介绍美国FCC+UL欧盟CE+ROHS日本PSE+METI备案+英国UKCA

美国 &#xff1a; FCC认证 &#xff1a;产品进入美洲市场的通行证&#xff0c;需通过FCC SDOC认证。 FCC第15部分B: 该标准适用于非故意辐射设备&#xff0c;如家用电器、电脑设备等。它规定了这些设备在电磁环境中不会产生过多的辐射。 ​射频标准: FCC第15部分C:该标准适…...

Flutter Isolate解决耗时任务导致卡死

先来对比一下在Flutter的ui主线程下直接计算一个耗时任务的情况&#xff1a; import package:flutter/material.dart;void main() {runApp(const MaterialApp(home: H(),)); }class H extends StatefulWidget {const H({super.key});overrideState<H> createState() >…...

使用deepseek快速创作ppt

目录 1.在DeekSeek生成PPT脚本2.打开Kimi3.最终效果 DeepSeek作为目前最强大模型&#xff0c;其推理能力炸裂&#xff0c;但是DeepSeek官方没有提供生成PPT功能&#xff0c;如果让DeepSeek做PPT呢&#xff1f; 有个途径&#xff1a;在DeepSeek让其深度思考做出PPT脚本&#xf…...

STM32的HAL库开发---高级定时器---输出比较模式实验

一、高级定时器输出比较模式实验原理 定时器的输出比较模式总共有8种&#xff0c;本文使用其中的翻转模式&#xff0c;当TIMXCCR1TIMXCNT时&#xff0c;翻转OC1REF的电平&#xff0c;OC1REF为输出参考信号&#xff0c;高电平有效&#xff0c;OC1REF信号连接到0C1上面&#xff…...

python Excel 表读取合并单元格以及清除空格符

读取合并单元格并保留合并信息 读取合并单元格并保留合并信息清除各单元格的空格和换行符&#xff0c;并去除列名中的空格和换行符 读取合并单元格并保留合并信息 当我们只是使用 pandas 的 read_excel 方法读取 Excel 文件时&#xff0c;我们可能会遇到一个很棘手的问题&…...

额外题目汇总2-链表

链表 1.24. 两两交换链表中的节点 力扣题目链接(opens new window) 给定一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后的链表。 你不能只是单纯的改变节点内部的值&#xff0c;而是需要实际的进行节点交换。 思路 使用虚拟头结点会很方便&#xff…...

C#控件开发6—指示灯

按钮功能&#xff1a;手自动旋转&#xff0c;标签文本显示、点击二次弹框确认&#xff08;源码在最后边&#xff09;&#xff1b; 【制作方法】 找到控件的中心坐标&#xff0c;画背景外环、内圆&#xff1b;再绘制矩形开关&#xff0c;进行角度旋转即可获得&#xff1b; 【关…...

探索从传统检索增强生成(RAG)到缓存增强生成(CAG)的转变

在人工智能快速发展的当下&#xff0c;大型语言模型&#xff08;LLMs&#xff09;已成为众多应用的核心技术。检索增强生成&#xff08;RAG&#xff09;&#xff08;RAG 系统从 POC 到生产应用&#xff1a;全面解析与实践指南&#xff09;和缓存增强生成&#xff08;CAG&#x…...

【学习总结|DAY036】Vue工程化+ElementPlus

引言 在前端开发领域&#xff0c;Vue 作为一款流行的 JavaScript 框架&#xff0c;结合 ElementPlus 组件库&#xff0c;为开发者提供了强大的构建用户界面的能力。本文将结合学习内容&#xff0c;详细介绍 Vue 工程化开发流程以及 ElementPlus 的使用&#xff0c;助力开发者快…...

【GitHub】GitHub 2FA 双因素认证 ( 使用 Microsoft Authenticator 应用进行二次验证 )

文章目录 一、GitHub 的 2FA 双因素认证二、使用 Microsoft Authenticator 应用进行二次验证1、TOTP 应用2、下载 Microsoft Authenticator 应用3、安装使用 Authenticator 应用 三、恢复码重要性 一、GitHub 的 2FA 双因素认证 现在登录 GitHub 需要进行二次身份验证 ; 先登录…...

c# 2025/2/7 周五

13.《表达式&#xff0c;语句详解1》 18未完。。 表达式&#xff0c;语句详解_1_哔哩哔哩_bilibili...

蓝桥杯思维训练(五)

文章目录 子集II1191.K次串联后最大子数组之和 子集II 子集II 思路分析&#xff1a; 求解子集的问题的关键就是&#xff0c;通过递归与回溯&#xff0c;我们就是得确定以某个元素开始的子集&#xff0c;对于这个题目来说&#xff0c;比较麻烦的一点就是&#xff0c;存在重复的…...

I.MX6ULL 中断介绍下

GIC重点寄存器 1.中断分发器寄存器&#xff08;Distributor register &#xff09; a.Distributor Control Register(中断分发控制寄存器), GICD_CTLR Purpose Enables the forwarding of pending interrupts from the Distributor to the CPU interfaces 使能将挂起的中断从…...

Elasticsearch 生产集群部署终极方案

Elasticsearch 集群部署 1.集群部署1.1 新增用户1.2 优化操作系统1.3 JDK1.4 elasticsearch1.5 开机自启动 2.安全认证功能2.1 生成CA证书2.2 生成密钥2.3 上传至其他节点2.4 修改属主、属组2.5 配置文件添加参数2.6 各节点添加密钥库密码2.7 设置用户密码 1.集群部署 1.1 新增…...

Python用langchain、OpenAI大语言模型LLM情感分析苹果股票新闻数据及提示工程优化应用...

全文链接&#xff1a;https://tecdat.cn/?p39614 本文主要探讨了如何利用大语言模型&#xff08;LLMs&#xff09;进行股票分析。通过使用提供的股票市场和金融新闻获取数据&#xff0c;结合Python中的相关库&#xff0c;如Pandas、langchain等&#xff0c;实现对股票新闻的情…...

【正点原子K210连载】第六十七章 音频FFT实验 摘自【正点原子】DNK210使用指南-CanMV版指南

第六十七章 音频FFT实验 本章将介绍CanMV下FFT的应用&#xff0c;通过将时域采集到的音频数据通过FFT为频域。通过本章的学习&#xff0c;读者将学习到CanMV下控制FFT加速器进行FFT的使用。 本章分为如下几个小节&#xff1a; 32.1 maix.FFT模块介绍 32.2 硬件设计 32.3 程序设…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...