Spring事务为什们会失效呢?
下文笔者讲述Spring事务失效的场景简介说明,如下所示
1.2方法不是public类型的
今天被灵魂拷问: Spring事务咋失效了呢? 请简述哪些场景会导致事务失效呢? 下面笔者将描述事务失效的场景: 1.Spring中未启用事务管理器 2.方法不是public类型 3.数据源未配置事务管理器 4.本身调用问题 5.异常类型错误 6.异常被catch掉了 7.业务代码和Spring事务不在一个线程中
1.1未启用spring事务管理功能
@EnableTransactionManagement注解用于开启Spring事务 加入事务自动管理器中
1.2方法不是public类型的
@Transaction
可用在类上、接口上、public方法上
当我们将@Trasaction用于非public方法上
事务将无效
1.3数据源未配置事务管理器
spring是通过事务管理器了来管理事务的,一定不要忘记配置事务管理器了,要注意为每个数据源配置一个事务管理器:
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
1.4本身调用问题
spring是通过aop的方式
对需要spring管理事务的bean生成了代理对象
然后通过代理对象拦截了目标方法的执行
在方法前后添加了事务的功能
所以必须通过代理对象调用目标方法的时候,事务才会起效。
例
@Component
public class UserService {
public void m1(){
this.m2();
}
@Transactional
public void m2(){
//执行db操作
}
}
以上代码事务不会生效
因为m1中通过this的方式调用m2方法
而this并不是代理对象
this.m2()不会被事务拦截器
所以事务是无效的
当外部直接调用通过UserService这个bean来调用m2方法,事务是有效
对代码进行以下调整
如下:
@1在UserService中注入了自己
此时m1中的m2事务是生效的
@Component
public class UserService {
@Autowired //@1
private UserService userService;
public void m1() {
this.userService.m2();
}
@Transactional
public void m2() {
//执行db操作
}
}
1.5异常类型错误
spring事务回滚的机制
对业务方法进行try catch
当捕获到有指定的异常时
spring自动对事务进行回滚
如果我们程序对catch进行了处理,那么spring就无法捕捉异常,则无法处理异常
---也可以指定回滚的异常
@Transactional(rollbackFor = {异常类型列表})
1.6异常被处理了
业务代码自己对catch进行了处理
使Spring无法感知到异常
所以无法回滚
例:事务无效的代码
@Transactional
public void m1(){
事务操作1
try{
事务操作2
内部抛出了异常
}catch(Exception e){
}
}
1.7业务和spring事务代码必须在一个线程中
spring事务
实现中使用ThreadLocal
使一个线程中共享一个事务连接,如果不在一个线程中
则无法共用一个事务(因为Spring底层的事务实质是数据库的事务)
例:
@Transactional
public void m1() {
new Thread() {
一系列事务操作
}.start();
}
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。