千家信息网

遇到Spring双层事务不回滚怎么办

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,今天就跟大家聊聊有关遇到Spring双层事务不回滚怎么办,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。最近有粉丝在朋友圈问我,面试遇到了Spr
千家信息网最后更新 2026年11月01日遇到Spring双层事务不回滚怎么办

今天就跟大家聊聊有关遇到Spring双层事务不回滚怎么办,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

最近有粉丝在朋友圈问我,面试遇到了Spring双事务不会滚问题,怎么破解。下面结合一个简单案例,希望能解决一部分人的疑惑。

系统 A 调用系统 B 执行数据同步,系统 B 返回了错误提示,系统 A 需要将前边保存的回滚掉,同时把错误信息向上抛。

大致代码如下

@Service("noteService")
public class NoteServiceImpl implements NoteService {

@Resource
private SearchService searchService;


@Transactional(rollbackFor = Throwable.class)
@Override
public CommonResponse save(NoteEntity note) {
// 一系列 DB 操作

try {
searchService.sync(note);
} catch (Exception e) {
e.printStackTrace();
}

return CommonResponse.success(entity);
}

}

@Service("searchService")
public class SearchServiceImpl implements SearchService {

@Transactional(rollbackFor = Throwable.class)
@Override
public void sync(NoteEntity note) {
// 一系列 DB 操作

throw new RuntimeException("同步异常! [XXX]");
}

}

@SpringBootTest
public class NoteTests {

@Resource
private NoteService noteService;

@Test
public void saveNote() {
NoteEntity entity = new NoteEntity();
entity.setTitle("念奴娇赤壁怀古");
entity.setContent("大江东去,浪淘尽,千古风流人物。故垒西边,人道是:三国周郎赤壁。。。");
entity.setTags("苏轼,宋代");
entity.setCategory("苏轼诗词");

try {
noteService.save(entity);
} catch (Exception e) {
e.printStackTrace();
// FIXME 我想在这里拿到的是 同步异常! [XXX]
// FIXME 但是这里拿到的是 Transaction silently rolled back because it has been marked as rollback-only
System.out.println(">>>>>>>>>> " + e.getMessage());
}
}

}

事出有因

代码历史久远,为何这样写已无从追溯。

纳闷了一会儿,看到双层事务,就想起了 Spring事务传播机制,前边理解得比较肤浅。

没有特殊的配置,自然是走默认的事务传播机制了,也就是 Propagation.REQUIRED。

国际惯例,列出事务传播机制:

1、PROPAGATION_REQUIRED
当前没事务,则创建事务;存在事务,就加入该事务,这是最常用的设置。

2、PROPAGATION_SUPPORTS
当前存在事务,就加入事务,当前不存在事务,就以非事务方式执行。

3、PROPAGATION_MANDATORY
当前存在事务,就加入事务;当前不存在事务,就抛出异常。

4、PROPAGATION_REQUIRES_NEW
无条件创建新事务。

5、PROPAGATION_NOT_SUPPORTED
以非事务方式执行,如果当前存在事务,就将当前事务挂起。

6、PROPAGATION_NEVER
以非事务方式运行,如果存在事务,就抛出异常。

7、PROPAGATION_NESTED
开始执行事务前,先保存一个savepoint,当发生异常时,就回滚到savepoint;没有异常时,跟着外部事务一起提交或回滚。

具体原因

1、看了上边的事务传播机制,继续细化问题,内外层共用一个事务,内层抛出异常,会导致整个事务失败。

2、继续分析,外层逻辑进行了 try catch,就导致内层的异常无法继续向上抛出,外层事务会继续提交。

3、事务提交时,进行事务状态的判断,就发现这个事务是失败的,需要回滚,所以抛出了 Transaction silently rolled back because it has been marked as rollback-only 的异常。

怎么解决?

根据业务场景选择合适的方案。

1、当前这种场景,直接把外层逻辑中的 try catch 去掉即可。异常直接向上抛,事务就不会继续提交,调用方拿到的就是一手的异常;

2、如果内层不是核心逻辑,记录个日志啥的,可以把内层事务配置为 @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRES_NEW), 无论如何,都创建新的事务,外层事务不受内层事务影响。但是有个问题,外层事务失败了,内层事务还是把记录入库了,有可能产生脏数据;

3、如果外层事务失败了,内层事务也不能提交,那就可以使用 @Transactional(rollbackFor = Throwable.class, propagation = Propagation.NESTED)。注意:hibernate/jpa 不支持嵌套事务 NESTED,可用 JdbcTemplate 代替。

最后,下面这位粉丝总结的事务不生效问题,大家牢记。面试中能全说出来,Offer基本稳了。

看完上述内容,你们对遇到Spring双层事务不回滚怎么办有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。

事务 内层 外层 机制 系统 问题 传播 双层 内容 方式 逻辑 同步 代码 场景 数据 粉丝 苏轼 错误 赤壁 支持 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网络科技 上海挚品互联网科技有限公司 上海睿民互联网科技有限公司 A股互联网金融科技公司 科技类互联网 互联网科技排名 致聘互联网科技 互联网科技缩写 中正互联网科技招聘 互联网实体化科技化 成都互联网科技公司工作好不好 互联网媒体平台算高科技产业 华夏恒生互联网科技013171 恒生互联网科技业指数调整周期 锡山区互联网智能科技产品供应 互联网第三次科技革命特征 上海乐五互联网科技有限公司 科技互联网专业工作会议发言稿 数字科技和互联网金融哪个好 互联网领先科技成果宣传视频 互联网科技公司简介 互联网的科技创新 互联网金融科技创新 互联网科技公司有哪些 国外互联网科技网站 荆州市昕露互联网络科技有限公司 互联网科技扶贫时间 允成互联网科技有限公司融资 上海创道互联网络科技有限公司 唐山双旺合互联网科技产业园
0