当前位置:网站首页>月薪10k-20k都无法回答的事务问题,你会吗?
月薪10k-20k都无法回答的事务问题,你会吗?
2022-04-23 03:15:00 【小道仙97】
今天朋友扔来一个“简单”的事务代码,初看无味,再看惊奇。
也问了身边的一些朋友无一人回答正确,你也试试?
@Service
public class TestService {
@Autowired
private TestMapper testMapper;
@Autowired
private TestServiceTwo testServiceTwo;
@Transactional(rollbackFor = Exception.class)
public String funOne(){
// 这个就是一个简单的insert语句
testMapper.insert("a");
try {
testServiceTwo.funTwo();
}catch (Exception e){
System.out.println("异常了~~~");
}
return "da";
}
}
@Service
public class TestServiceTwo {
@Transactional(rollbackFor = Exception.class)
public void funTwo(){
throw new RuntimeException("DASDASDA");
}
}
问:最后数据库插入了几条数据?(答案放在文中)
下面有几个结论我们一个个去证明,看完你就会明白了。
一、spring基于注解的事务是基于代理的,不走代理,被调用的方法就不受事务管理代码的控制
所谓代理其实就是是否是用过依赖注入的,如果我们手动new一个对象,或者直接去调用本类的方法则不走代理。
通过下面这个代码可以打印出当前事务的hashCode
,如果hashCode
相同则认为是同一个事务。
TransactionAspectSupport.currentTransactionStatus().hashCode()
-
可以把它放在上面的
funOne
和funTwo
里面,发现最后打印出来的hashCode
并不相同。 -
如果我们调用
funTwo
的时候,并不使用@Autowired
的方式,而是使用new
的方式,你会发现打印的hashCode
确是相同的。 -
- TestServiceTwo two = new TestServiceTwo();
-
- two.funTwo();
-
如果去掉方法
funTwo
上面的@Transactional
注解,再次打印的hashCode
也是相同的。 -
如果不去调用
funTwo
,而是去调用和funOne
同类(同一个类)的funThree
,打印的hashCode
也是相同的。
注:如果hashCode
相同那么说明是用一个事务。
二、嵌套事务如果子事务抛出了异常,父事务同样会回滚,并且会抛出一个异常
Transaction rolled back because it has been marked as rollback-only
其实这个结论就在本题的结果,最后没有插入一条数据,原因就是父事务也回滚了。
funOne
调用funTwo
,funOne
中抓了funTwo
的异常,当funTwo
发生异常的时候,funTwo
的操作应该回滚,但是funOne
吃了异常,funOne
方法中没有产生异常,所以funOne
的操作又应该提交,二者是相互矛盾的。
spring的事务关联拦截器在抓到funTwo
的异常后就会标记rollback-only为true,当funOne
执行完准备提交后,发现rollback-only为true,也会回滚,并抛出异常告诉调用者。
但也不是绝对的,我们知道上面的两个事务虽然是独立的两个事务,但是依旧是有关联的,你可以理解成关联事务(就是上面所说spring的事务关联拦截器…)
如果我们让其事务不进行关联,是两个独立的事务,也就是说不会抛出rollback-only
这个异常,那么funOne
就不会回滚。
事务的传播行为有很多种,默认是REQUIRED
,我们改成REQUIRES_NEW
,再来试试结果发现是插入了一条数据的。
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
事务的传播行为:
value | desc |
---|---|
REQUIRED (默认) | 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择 |
SUPPORTS | 支持当前事务,如果当前没有事务,就以非事务方式执行 |
MANDATORY | 支持当前事务,如果当前没有事务,就抛出异常 |
REQUIRES_NEW | 新建事务,如果当前存在事务,把当前事务挂起 |
NOT_SUPPORTED | 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起 |
NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常 |
NESTED | 支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务 |
注:这里的当前事务和我们一般理解有些不同,不是它的父事务。
三、如果在同一个事务内,不管是父方法异常,还是子方法异常,全部会回滚。(如果把异常try catch
,则不会)
这里的同一个事务指(其实我们可以通过打印hashCode
的方式来判断)
- 同一个类去调用子方法
- 调用另外一个类的没有
@Transactional
的方法
eg:
@Service
public class TestService {
@Autowired
private TestMapper testMapper;
@Transactional(rollbackFor = Exception.class)
public String funOne(){
testMapper.insert("a");
funThree();
return "das";
}
public void funThree(){
int i = 1 / 0;
}
}
版权声明
本文为[小道仙97]所创,转载请带上原文链接,感谢
https://blog.csdn.net/Tomwildboar/article/details/118738229
边栏推荐
- Web Course Design - his system
- [Mysql] LEFT函数 | RIGHT函数
- Five tips for cross-border e-commerce in 2022
- Flink实时数仓项目—DWS层设计与实现
- [Mysql] LEFT函數 | RIGHT函數
- 研讨会回放视频:如何提升Jenkins能力,使其成为真正的DevOps平台
- If the deep replication of objects is realized through C #?
- js递归树结构计算每个节点的叶子节点的数量并且输出
- 全网讲的最细,软件测试度量,怎样优化软件测试成本提高效率---火爆
- 荐读 | 分享交易员的书单,向名家请教交易之道,交易精彩无比
猜你喜欢
一套组合拳,打造一款 IDEA 护眼方案
Xutils3 corrected a bug I reported. Happy
2022年P气瓶充装培训试题及模拟考试
Course design of Database Principle -- material distribution management system
宁德时代地位不保?
Source generator actual combat
Blazor University (11) component - replace attributes of subcomponents
Laravel new route file
Peut recevoir plusieurs paramètres de type de données - paramètres variables
[MySQL] left Function | Right Function
随机推荐
12.<tag-链表和常考点综合>-lt.234-回文链表
Flink实时数仓项目—DWS层设计与实现
Mysql database
2022G2电站锅炉司炉考试题库及在线模拟考试
荐读 | 分享交易员的书单,向名家请教交易之道,交易精彩无比
Student achievement management
Creating wechat voucher process with PHP
A set of C interview questions about memory alignment. Many people make mistakes!
[MySQL] left Function | Right Function
使用DFS来解决“字典序排数”问题
Establishing and traversing binary tree
在.NE6 WebApi中使用分布式缓存Redis
Swap the left and right of each node in a binary tree
編碼電機PID調試(速度環|比特置環|跟隨)
Top ten project management software similar to JIRA
Source generator actual combat
Simple example of using redis in PHP
Find the number of leaf nodes of binary tree
be based on. NETCORE development blog project starblog - (2) environment preparation and creation project
JS recursive tree structure calculates the number of leaf nodes of each node and outputs it