

spring事务里面开启线程插入,报错了是否会回滚? - wenbochang
source link: https://www.cnblogs.com/wenbochang/p/17311858.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

spring事务里面开启线程插入,报错了是否会回滚?
一道非常有意思的面试题目。大概是这样子的,如果在一个事务中,开启线程进行插入更新等操作,如果报错了,事务是否会进行回滚
示例1
@RequestMapping("/test/publish/submit")
public String testPublish1() {
log.info("start...");
transactionTemplate.execute(new TransactionCallback<String>() {
@Override
public String doInTransaction(TransactionStatus status) {
TElement element = new TElement();
element.setfElementId(10L);
element.setfElementName("111");
mapper.insertSelective(element);
element = new TElement();
element.setfElementId(10L);
element.setfElementName("222");
mapper.insertSelective(element);
return "OK";
}
});
log.info("end...");
return "ok";
}
示例2
@RequestMapping("/test/publish/submit2")
public String testPublish2() {
log.info("start...");
transactionTemplate.execute(new TransactionCallback<String>() {
@Override
public String doInTransaction(TransactionStatus status) {
es.submit(() -> {
TElement element = new TElement();
element.setfElementId(10L);
element.setfElementName("111");
mapper.insertSelective(element);
});
es.submit(() -> {
TElement element = new TElement();
element.setfElementId(10L);
element.setfElementName("222");
mapper.insertSelective(element);
});
return "OK";
}
});
log.info("end...");
return "ok";
}
element.setfElementId(10L); 为主键。SQL在第一次插入id=10的时候是没有问题的,在第二次插入id=10的时候,由于主键冲突了,导致报错,然后整个事务都会进行回滚,这是没有问题的。是spring的事务帮助我们来进行回滚等操作的。我们可以看到如下代码,他是对整个result = action.doInTransaction(status);进行了try catch。如果抛异常,就会回滚
@Override
@Nullable
public <T> T execute(TransactionCallback<T> action) throws TransactionException {
Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");
if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
}
else {
TransactionStatus status = this.transactionManager.getTransaction(this);
T result;
try {
result = action.doInTransaction(status);
}
catch (RuntimeException | Error ex) {
// Transactional code threw application exception -> rollback
rollbackOnException(status, ex);
throw ex;
}
catch (Throwable ex) {
// Transactional code threw unexpected exception -> rollback
rollbackOnException(status, ex);
throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
}
this.transactionManager.commit(status);
return result;
}
}
示例2首先是transactionTemplate.execute是一个主main线程。然后在第一个子线程插入了一个数据,第二个子线程也插入了一个数据。那么现在就是有三个线程,一个是main线程,一个是A线程,一个是B线程。
main线程正常执行不报错,A线程正常插入不报错,B线程由于主键冲突报错。
我们可以通过上面action.doInTransaction(status);看出来,他对这块代码进行了try catch。也就是主线程进行了try catch。那么也就是只要主线程没有报错,这个事务就不会被捕获,也就不会回滚了。无论你A,B还是CDEFG子线程出问题了,只要不影响main线程,那事务就不会回滚呢?
因此我们可以得出一个结论,在示例2中,A线程会插入成功,B线程插入失败,事务不会回滚,最终插入成功。这个其实与我们平常的想法所违背了。
因此如果想要主线程抛出异常,得让主线程感知到子线程异常了,主动地去throw异常。比如我们可以设置一个flag,子线程报错了 flag=true。主线程检测到flag为true,就主动抛出一个exception
这道面试题非常有意思,起初以为会回滚,没想到不会回滚。查看代码得知,原来是catch住的是主线程,并不是子线程。同样注解式事务类似。因此如果想要事务生效,尽量避免在事务中使用多线程来进行插入更新等操作
Recommend
-
50
0. 写在最前面 一直想成为讲故事很厉害,无奈自己从小语文就不好,讲话写东西也是流水账的风格,如果各位大佬觉得无聊,直接拉到最后看面经即可。 大概去年的一月份左右,我也比较迷茫。这份迷茫源于,不清楚自
-
51
macOS - @jiujiii - 分享一个在 win10 里面的实现方式楼主之前都是用的 Windows10 ,在 win10 里面,我是这样做的:1.在一个新建的文件夹里面加入我要使用的所有软件的快捷方式(重点)
-
9
一、抛出问题关于如何计算并发线程数,一般分两派,来自两本书,且都是好书,到底哪个是对的?问题追踪后,整理如下:第一派:《Java Concurrency in Practice》即《java并发编程实践》,如下图:如上图,在《Java Concurrency in Practice》一书中,给出了估算线...
-
25
这是why技术的第 74 篇原创文章 深夜怼文的我 别问,问就是不行 分布...
-
6
从事务的基础知识到一些核心源码的分析,然后逐步引入到分布式事务的常用解决方案,以及分布式事务核心框架源码的讲解。 (本系列持续更新,感兴趣请关注我的公众号,不错过下一波干货)。 上面一篇已经完成了源码的入门,我们已经...
-
6
V2EX › MySQL 在一个事务内插入大量数据会怎么样 git00ll · 16 小时 51 分钟前 · 1459...
-
6
我们之前搭建了第一个docker项目: windows环境30分钟从0开始快速搭建第一个docker项目(带数据库交互):
-
9
springboot 里面增删改查怎么用多线程写,持久层是mybatis 魔力猫...
-
9
V2EX › C++ VS2019 可以在 DllMain 里面创建线程, VS2017 则会被一直挂起? Kasumi20 ·
-
6
Spring在多线程环境下如何确保事务一致性 精选 原创 囡囡的马小胖 202...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK