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

本地电脑如何做网站服务器全网营销推广怎么收费

本地电脑如何做网站服务器,全网营销推广怎么收费,帝国cms影视网站模板,建设企业网站企业网银最近我们在排查一个诡异的 空指针异常,整个分析过程可以说是跌宕起伏,最终的结论也颇具隐蔽性。今天就把这个问题分享出来,希望对大家有所帮助。 问题现象 在系统中,我们有 单据 B,它通过一个 关联 ID 字段与 上级单…

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

问题现象

在系统中,我们有 单据 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方法,降低了死锁发生的概率。希望这次排查经历,能给大家一些启发!🚀🚀🚀

http://www.yayakq.cn/news/685417/

相关文章:

  • 网站建设推广文章做网站和做免费推广网站的区别
  • 网站静态页面模板wordpress 后台精简
  • 主机建网站的优势wordpress商业模板个人
  • 新手搭建网站wordpress 永久链接
  • cms建站方案简单描述什么是网络营销
  • 邮件验证登录网站开发建设企业网站综合考虑
  • 厦门人才网官方网站建设路小学网站
  • 永兴网站建设湖北省建设工程质量协会网站
  • 网站建设报告家教总结wordpress置顶 显示
  • 网站建设_seo技术支持眼镜网站怎么做
  • 网站开发步奏跨境电商物流模式主要有哪些
  • 旅游网站建设风格襄阳大摩网站建设
  • 湖南做网站 多少钱磐石网络代理网址大全
  • 惠新西街网站建设城市网站建设意义
  • 哪个网站有免费ppt下载查找网站
  • 佛山网站优化平台哪里有营销型网站制作
  • 鹿城区住房和城乡建设局网站phpcms如何发布网站
  • 杭州网站设计 网站商城网站系统建设
  • 推荐佛山顺德网站建设微信小程序开发视频教程
  • 可信网站认证服务商a站全称
  • 莱西做网站公司关于自行建设门户网站的请示
  • 轴承网站建设wordpress喜欢插件
  • 企业网站源码挣钱吗梁朝伟做汤唯视频网站
  • 建设网站 软件wordpress菜单栏下拉
  • 网站开发后端做什么河南百度建个网站
  • 安徽省建设厅执业资格注册中心网站做暧暧网站在线看
  • 网站怎么做展现量珠海企业模板建站
  • 重庆市企业网站建设长沙网站设计咨询电话
  • 微网站 制作网站如何接广告赚钱
  • 做的最好的相亲网站上海什么做网站的公司比较好