事务崩了别怪数据库!三大核心要素没掌握才是根本原因

原文来自于:zha-ge.cn/java/111

事务崩了别怪数据库!三大核心要素没掌握才是根本原因

说真的,每次上线修 Bug 遇到"事务失效"这四个字,我都想立马上楼顶冷静一下。数据库被程序员骂了无数次,但不少时候还真不能怪它------大多数雷,都是我们自己埋下的。

上周同事阿伟又一次喊我:"快救命!数据库的事务不起作用,全表更新没回滚,库存炸啦!"哈哈,他这口气像极了觉得自己一点问题都没有,锅都是 MySQL 的锅。我淡定问了句:"你是不是只知道 commit/rollback,三大要素你搞清楚了没?"

他一脸懵逼:"啥三大要素?"------好家伙,这就是故事的开始。


那些年,我们踩过的事务"坑"

其实 Java 世界说到事务,基本都是和 Spring @Transactional 打交道的,我总结了下,大家踩雷最密集的,有这么几个典型瞬间:

  • 隔离级别?"反正默认就行吧"------结果脏读、幻读满天飞。
  • 传播机制?"我外层有@Transactional就行"------结果内层事务意外失效。
  • 回滚机制?"抛了异常不是自动回滚吗?"------结果 checked exception 扑面而来,程序一脸懵。

我问阿伟:"你是不是下面这种典型用法?" 他翻出代码,果然如此朴实无华:

java 复制代码
@Transactional
public void updateStock() {
    // ...更新多张表
    if (xxx) {
        throw new Exception("看似会回滚......");
    }
}

槽点来了,所以说"抛异常自动回滚",你确定吗?其实只有 RuntimeException(也就是未检查异常)才会自动触发 Spring 的回滚逻辑,普通 Exception 可没这待遇。


踩坑瞬间

那天帮阿伟查 Bug,咱们上真家伙:

  • 问题核心1:checked exception
    • 他抛的是 Exception(checked),Spring 并不会自动 rollback。
    • 解决办法:@Transactional(rollbackFor = Exception.class)
  • 问题核心2:自行catch住例外
    • 代码里 try-catch 把所有异常吞了,Spring 当然检测不到异常发生,事务照常提交。
  • 问题核心3:不懂传播机制
    • 方法自己调用自己,@Transactional 无效......Spring AOP 懂的都懂。

有图有真相,主要地方关键几行:

java 复制代码
@Transactional(rollbackFor = Exception.class)
public void outerMethod() {
    try {
        innerMethod();
    } catch (Exception e) {
        // 没抛出,没回滚
        log.error("被我 catch 住了");
    }
}

啧啧,各种防不胜防。


经验启示

后来,阿伟终于明白这三大核心要素了:

要素 懒人误区 你该咋搞
隔离级别 "默认就行!" 了解脏读、幻读风险
传播机制 "随便加个注解" 明白 REQUIRED/REQUIRES_NEW 区别
回滚机制 "随便抛个异常" Runtime、自定 rollbackFor、避免异常被吞

所以别再张口闭口"数据库背锅,MySQL太坑",其实各种事务悬案,80%是自己代码写崩的。


讲完了,收个尾巴: 踩坑不可怕,搞明白才是大佬。下一次,事务失效不要再冤枉你家数据库,先照照镜子想想,是不是自己三大要素没掌握。最后,用一句朋友总结的话:"你只要敢乱用@Transactional,坑就会如影随形。"

下班,溜了~

相关推荐
Gomiko2 小时前
JavaScript DOM 原生部分(五):事件绑定
开发语言·前端·javascript
无限大62 小时前
为什么显示器分辨率越高越清晰?——从像素到 4K/8K 的视觉革命
后端
巴拉巴拉~~2 小时前
Flutter 通用下拉选择组件 CommonDropdown:单选 + 搜索 + 自定义样式
开发语言·javascript·ecmascript
阿苟2 小时前
nginx部署踩坑
前端·后端
Можно2 小时前
深入理解 JavaScript 函数:分类、特性与实战应用
开发语言·javascript
ChineHe3 小时前
Gin框架基础篇001_路由与路由组详解
后端·golang·gin
神奇小汤圆3 小时前
深入理解Linux IPIP隧道:原理、配置与实战
后端
lionliu05193 小时前
JavaScript 变量声明最佳实践
前端·javascript·vue.js
计算机毕设VX:Fegn08953 小时前
计算机毕业设计|基于springboot + vue酒店管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
AAA阿giao3 小时前
从零开始学 React:用搭积木的方式构建你的第一个网页!
前端·javascript·学习·react.js·前端框架·vite·jsx