spring事务失效原因

转载自:spring事务失效的原因
spring事务失效的原因是什么?我们如何解决?下面我们一起来了解一下!

Spring失效原因
事务失效的原因和解决方案
服务没有开启事务管理

原因:没有开启事务管理,Spring无法创建事务代理对象,导致事务不生效

解决方案:springBoot服务在application上添加@EnableTransactionManagement注解

@SpringBootApplication
@EnableTransactionManagement
public class A{
    public static void main(String[] args) {
        SpringApplication.run(A.class, args);
    }
}

2.Service没有交由spring进行管理

原因:Spring事务是由AOP机制实现的,也就是说从Spring IOC容器获取bean时,Spring会为目标类创建代理,来支持事务的。但是service没有添加@Service被注解,spring无法管理当前service,也就无法支持事务

解决方案:service上添加@Service注解

@Service
public class DemoServiceImpl{
    //业务方法。。。。。。。
} 

3.使用了错误的事务传播机制

原因:Propagation.NOT_SUPPORTED传播特性不支持事务。

解决方案:选择正确的事务传播机制

@Service
public class DemoServiceImpl{ 

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
public String  baseInfo(String param) { 
 	 //业务逻辑。。。。。。。       
 return "test";
    }
}

4.同一个类中,方法内部调用

@Service
public class DemoServiceImpl{ 

     public  void A(){
        B();
    }
    @Transactional
    public  void B(){
        //处理业务逻辑
    }
}

DemoServiceImpl中方法A中调用了方法B,方法B加了@Transactional注解,但是方法B事务处理仍失效了

失效原因:事务是通过Spring AOP代理来实现的,而在同一个类中,一个方法调用另一个方法时,调用方法直接调用目标方法的代码,而不是通过代理类进行调用。所以调用目标executeAddTianLuo方法不是通过代理类进行的,因此事务不生效。

解决方案:新建一个类,将方法放在不同类中

5.方法的访问权限不是public

@Service
public class DemoServiceImpl{ 
   @Transactional
    private void A(){
        //处理业务逻辑
    }
}

原因:spring事务方法A的访问权限不是public,事务不生效,因为Spring事务是由AOP机制实现的,AOP机制的本质就是动态代理,而代理的事务方法不是public的话,computeTransactionAttribute()就会返回null,spring就不再给方法添加事务属性 解决方法:将private 改为public

查看源码**************************************************************

/**

     * Same signature as {@link #getTransactionAttribute}, but doesn't cache the result.

     * {@link #getTransactionAttribute} is effectively a caching decorator for this method.

     * <p>As of 4.1.8, this method can be overridden.

     * @since 4.1.8

     * @see #getTransactionAttribute

     */

    @Nullable

    protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {

        // Don't allow no-public methods as required.

        if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {

            return null;

        }

        // The method may be on an interface, but we need attributes from the target class.

        // If the target class is null, the method will be unchanged.

        Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

        // First try is the method in the target class.

        TransactionAttribute txAttr = findTransactionAttribute(specificMethod);

        if (txAttr != null) {

            return txAttr;

        }

        // Second try is the transaction attribute on the target class.

        txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());

        if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {

            return txAttr;

        }

        if (specificMethod != method) {

            // Fallback is to look at the original method.

            txAttr = findTransactionAttribute(method);

            if (txAttr != null) {

                return txAttr;

            }

            // Last fallback is the class of the original method.

            txAttr = findTransactionAttribute(method.getDeclaringClass());

            if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {

                return txAttr;

            }

        }

        return null;

    }

6.事务方法被final、static关键字修饰

@Service
public class DemoServiceImpl{ 
   @Transactional
    public final void A(){
        //处理业务逻辑
    }
}

原因:如果一个方法被声明为final或者static,则该方法不能被子类重写,也就是说无法在该方法上进行动态代理,这会导致Spring无法生成事务代理对象来管理事务。
解决方法:事务方法不要用final或者static修饰。

7。数据库的存储引擎不支持事务

Spring事务的底层,还是依赖于数据库本身的事务支持。如果您使用的是mysql数据库,且数据库没有使用InnoDB存储引擎,那么事务会失效,另Spring事务的底层,还是依赖于数据库本身的事务支持。

解决办法:使用支持事务的引擎(mysql使用InnoDB)

8.方法中使用了try{}catch(Exception e){}捕获了异常

@Service
public class DemoServiceImpl{ 
   @Transactional
    public final void A(){
      Try{
         //处理业务逻辑
      }catch(Exception e){
        //异常处理逻辑
      }       
   }
}

原因:事务方法中如果我们使用try{}catch(Exception e){}捕获了异常,就会引起事务失效
解决办法:去掉try{}catch(Exception e ){}或者在 catch中抛出有效的异常

9.手动抛出了非RuntimeException异常

@Service
public class DemoServiceImpl{ 
   @Transactional( rollbackFor = Exception)
    public final void A(){
       Try{
         //处理业务逻辑
       }catch(Exception e){
         throw new Exception(“处理异常”);
       }      
    }
}

原因:Spring事务默认处理RuntimeException,对应手动抛出的非RuntimeException会导致事务失效

解决办法:我们可以配置@Transactional( rollbackFor = Exception)

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值