面试好题:@Transactional声明式事务注解什么时候会失效?
面试题:@Transactional声明式事务注解什么时候会失效
前言
今天来分享一道比较有意思的面试题,“@Transactional声明式事务注解什么时候会失效?”。
对于这个问题,我们一起看看考察点和比较好的回答吧!
考察点
这个问题就是面试官想考察我们对@Transactional注解有没有深刻的认识,以及日常开发中是否善于积累,认真思考。
回答
下面我从7个点来回答:
1.声明式事务主要是得益于SpringAOP,使用一个事务拦截器,在方法的调用前后/周围进行事务性的增强,来驱动事务的完成。其本质是通过生成一个代理子类,通过重写父类方法方式实现事务的代理增强!
2.事务失效场景1:注解在非public修饰的方法上,这是Spring强制要求的。
3.事务失效场景2:注解在final关键字修饰的方法上。原因是final关键字修饰的方法由于不能被子类重写,所以不能通过代理增强。
4.事务失效场景3:通过this调用方法,this关键字在jvm中指的是当前对象,而不是Spring代理后的代理对象,所以不具备事务增强的能力。
5.事务失效场景4:异常被try捕获,Spring事务默认只会回滚抛出RuntimeException类型异常,如果异常被try,事务不会被回滚。
@Transcational
public void method(){
try{
//业务代码
}catch(Exception e){
e.printStackTrace();
}
}
6.事务失效场景5:抛出非RuntimeException类型异常且没有指定rollbackFor。Spring注解事务在没有手动指定rollbackFor参数的情况下,默认只会回滚抛出RuntimeException异常,可以通过手动指定rollbackFor参数改变这个策略。
7.事务失效场景6:新开线程处理。Spring事务管理器底层是通过ThreadLocal的原理来管理事务(ThreadLocall可以实现多线程下对共享资源访问的安全性保证)。但是无法控制跨线程之前的事务一致性。
@Transcational
public void methodB(){
new Thread(new Runnable(){
@Override
public void run(){
//insert into xxxx
//update xxx
//throw new RuntimeException
}
});
}
以上就是我对于这个问题的理解。
总结
这个问题主要是考察求职者对Spring中事务基础能力的掌握。在实际应用中,声明式事务和编程式事务是非常重要和常见的功能,对于这部分内容如果理解不够深刻,很容易造成事务不生效的问题。希望读完这篇文章你有所收获。欢迎转发,关注微信公众号:程序员的故事,了解更多精彩面试题。