Spring中的事务

18 篇文章 0 订阅
11 篇文章 0 订阅
Spring中的事务

@Transactional 注解是通过动态代理实现的

如果你在方法中有try{}catch(Exception e){}处理,那么try里面的代码块就脱离了事务的管理,若要事务生效需要在catch中throw new RuntimeException (“xxxxxx”);这一点也是面试中会问到的事务失效的场景

事务的失效的场景:

  • 在@Transactional注解的方法中,再调用本类中的其他方法method2时,那么method2方法上的@Transactional注解是不!会!生!效!的!但是加上也并不会报错。
  • @Transactional注解的方法必须是公共方法,就是必须是public修饰符!!!
    • 因为JVM的动态代理是基于接口实现的,通过代理类将目标方法进行增强,没有权限访问就无法进行增强
@Transactional
//@Transactional(propagation = Propagation.REQUIRES_NEW)//各自保持事务一致性
public static void method1(Map<String,Object> params){
    System.out.println("入参数据:"+params);
    method2(params);
    System.out.println("结果数据:"+res);
}

@Transactional//不会生效
//@Transactional(propagation = Propagation.REQUIRES_NEW)//各自保持事务一致性
public static void method2(Map<String,Object> params){
    System.out.println("入参数据:"+params);
    String res = method2(params);
   throw new RuntimeException("手动抛出异常。。。");
}

@Transactional
public static void main(){
    Map<String,Object> params = new HashMap<String,Object>();
    params.put("test","测试事务。。。");
    method1(params);
    method2(params);
}

小结:

  • 只要方法main上有@Transactional注解,并且方法method1和方法method2都处于当前(main)事务中,(不使用代理调用,方法method1和方法method2上的@Transactional注解是不生效的;使用代理,需要方法method1和方法method2都处在main方法的事务中,默认或者嵌套事务均可,当然也可以不加@Transactional注解),那么便可以保持整体事务一致性。
@Transactional(propagation = Propagation.REQUIRES_NEW)//各自保持事务一致性
public static void method1(Map<String,Object> params){
    System.out.println("入参数据:"+params);
    method2(params);
    System.out.println("结果数据:"+res);
}

@Transactional(propagation = Propagation.REQUIRES_NEW)//各自保持事务一致性
public static void method2(Map<String,Object> params){
    System.out.println("入参数据:"+params);
    String res = method2(params);
   throw new RuntimeException("手动抛出异常。。。");
}

@Transactional
public static void main(){
    Map<String,Object> params = new HashMap<String,Object>();
    params.put("test","测试事务。。。");
    method1(params);
    method2(params);
}
  • 要方法method1和方法method2均单独保持事务一致性:如果不是用代理调用@Transactional注解是不生效的,所以一定要使用代理调用实现,然后让方法method1和方法method2分别单独开启新的事务。
    • 在事务注解中使用propagation = Propagation.REQUIRES_NEW使事务保持单独一致性;
    • @Transactional(propagation = Propagation.REQUIRES_NEW)使方法各自保持事务一致性。
    • 或者在主方法(main)上不添加``@Transactional注解,在各自方法上添加 @Transactional`注解来保持各自的事务独立性。
@Transactional //各自保持事务一致性
public static void method1(Map<String,Object> params){
    System.out.println("入参数据:"+params);
    method2(params);
    System.out.println("结果数据:"+res);
}

@Transactional //各自保持事务一致性
public static void method2(Map<String,Object> params){
    System.out.println("入参数据:"+params);
    String res = method2(params);
   throw new RuntimeException("手动抛出异常。。。");
}
//不添加 @Transactional 事务注解
public static void main(){
    Map<String,Object> params = new HashMap<String,Object>();
    params.put("test","测试事务。。。");
    method1(params);
    method2(params);
}

小结:

  • 1、就是@Transactional注解保证的是每个方法处在一个事务,如果有try一定在catch中抛出运行时异常。
@Transactional
public static void main(){
     Map<String,Object> params = null;
   try{
       params.get("test");
   }catch(Exception e){
       throw new RuntimeException();
   }
}
  • 2、方法必须是public修饰符。否则注解不会生效,但是加了注解也没啥毛病,不会报错,只是不起作用。
@Transactional //使用private时该注解不起作用,必须为public才可
private static void main(){
     Map<String,Object> params = null;
   try{
       params.get("test");
   }catch(Exception e){
       throw new RuntimeException();
   }
}
  • 3、this.本方法的调用,被调用方法上注解是不生效的,因为无法再次进行切面增强。
@Transactional//开启事务
public void main(){
    Map<String,Object> params = new HashMap<String,Object>();
    params.put("test","测试事务。。。");
    this.method1(params);
}

@Transactional // 该事务不会生效
public void method1(Map<String,Object> params){
    System.out.println("入参数据:"+params);
}
  • 4、try{}中的代码块会脱离Spring的事务,想要事务生效必须要在catch(){}中抛出RuntimeException运行时异常。此时出现异常后,Spring会捕获回滚,来保证事务的一致性。在throw new RuntimeException(“抛出异常了”);之前代码均处于同一事物中,所有内容都会回滚,包括catch(){}中的方法代码也会回滚掉。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值