当前位置: 首页 > news >正文

网站正在备案什么是网络营销 职能是什么

网站正在备案,什么是网络营销 职能是什么,饶阳营销型网站建设费用,企业邮箱免费注册入口Transactional注解失效的场景 Transactional依赖于spring对bean的调用,因为Transactional注解本质上是一个AOP,事务的回滚,开启,提交等相当于是通知,而spring事务管理相当于是切面,被注解的业务逻辑方法是切入点(这里起始不算是严格意义的AOP,但由于注解是声明式的标记而非高侵…

@Transactional注解失效的场景

@Transactional依赖于spring对bean的调用,因为@Transactional注解本质上是一个AOP,事务的回滚,开启,提交等相当于是通知,而spring事务管理相当于是切面,被注解的业务逻辑方法是切入点(这里起始不算是严格意义的AOP,但由于注解是声明式的标记而非高侵入式的代码,所以也可以算是AOP)

Spring事务时依赖于数据库事务的,在Spring事务是一个拦截器,在定义的事务方法开始前会向数据库申请一个事务,然后执行事务方法,如果出现问题就向数据库申请回滚,如果正常执行完就申请提交

在某些情况下@Transactional注解会起不到应有的作用,具体分为四大类

代理机制未生效
自调用

由于@Transactional注解本质上是一个AOP,所以他生效是需要依赖于spring的事务管理的,所以如果一个方法调用本类的事务方法(被加了@Transactional注解),那么这个注解是无法生效的,因为直接调用本类的方法是先于spring的,也就相当于跳过了spring的事务管理,那么这个AOP就没有生效.

例如:

public class Example01 {public void tryA(){tryB();}@Transactionalpublic void tryB(){Example02 example02=new Example02();System.out.println("引用Example02类里的方法C");example02.tryC();System.out.println("引用Example02类里的方法D");example02.tryD();}
}

在A方法中引用本类的方法B,其中B方法中引用方法C和D且定义为事务,但由于A中直接引用本类方法B所以在A中B方法的事务性不生效,比如执行A方法,在执行过程中如果CD方法之间发生了异常,方法不会触发回滚,即已经执行的C方法不会回滚撤回,也就是@Transactional注解失效.

解决方法:

在本类定义为一个bean,在本类中自动装配一个本类bean,用这个bean来往A方法中引入B方法

@Service
public class Example01 {@Autowiredprivate Example01 example01;public void tryA(){example01.tryB();}@Transactionalpublic void tryB(){Example02 example02=new Example02();System.out.println("引用Example02类里的方法C");example02.tryC();System.out.println("引用Example02类里的方法D");example02.tryD();}
}

用自动装配的本类bean来调用本类方法是通过spring对方法进行调用所以事务可以正常进行

非Spring管理的类

事务是一个AOP,依赖于spring,如果没有注解本类让spring管理这个类注解就无法生效

非public方法

spring的AOP代理在处理事务的时候是默认跳过非public方法的,所以如果不是public方法就无法被spring代理,代理机制就无法生效,事务注解无法生效

异常处理不当

@Transactional注解只会对未被捕获的非受检异常(RuntimeException和Error)生效,触发回滚,如果方法中捕获了异常且未重新抛出,事务不会回滚

关于异常处理不当到底是否算作@Transactional注解失效的问题其实在我看来有待商榷,目前大多认为@Transactional失效的场景包括异常处理不当这一项,但我个人的理解中@Transactional注解在正常运行

首先理解受检异常和非受检异常两个概念,受检异常和非受检异常

受检异常就是可以预料有可能会出问题的地方,这部分异常是在出现之前可以想到的,通常IDE会强制开发人员处理(捕获处理或抛出)这部分异常,这部分异常既然已经被处理就不会影响程序的正常执行,例如b方法中有c方法和d方法,c和d之间有一个受检异常e,而e既然已经被处理,那么就是说即使没有开启事务,当e异常发生的时候,c和d仍然还是正常执行的,而将这种情况判定为注解失效主要是根据功能来分的,即事务进行过程中发生异常但未触发回滚,因此判定未注解失效,但本质上这是一个正常执行的程序

非受检异常就是无法预料到的异常,比如1/0这种,运行过程会出现异常,但提前无法预料(无法预料是指程序无法预料,程序员根据自己的经验做出的异常预料和处理跟这个无关),IDE不会对这部分异常强制开发人员处理,而这部分异常分为两种,程序员预料到了并进行了处理或程序员未预料到未捕获,若程序员预料到并进行了处理,那事务注解就不会生效,这原理其实和受检异常类似,而如果程序员未预料到未捕获,那这个异常相当于未曾经过任何处理,会导致程序出错无法继续执行,这时候事务注解就会生效触发回滚

总的来说异常总共有三类,已经被处理(包括捕获处理和抛出)的受检异常,已经被处理的非受检异常,未被处理的非受检异常,前两种在未定义事务的情况下也不会阻断程序继续往下执行,而最后的未捕获的非受检异常在未定义事务的情况下会直接阻断程序往下执行,造成代码行为的不连贯,出现操作不同步,通俗来讲就是只有最后一种是bug,前两种只是程序的正常行为,所以事务只会在最后一种bug的情况生效

而异常处理不当之所以会被归为@Transactional注解失效的情况之一主要是从行为上看程序出现了异常而无法触发回滚,见仁见智

解决方法:

如果要扩大@Transactional注解管理的范围,可以通过 @Transactional(rollbackFor = Exception.class) 指定需要回滚的异常类型。

如果要让被捕获的非受检异常也能触发回滚可以捕获异常后重新抛出(如 throw new RuntimeException(e)

事务配置错误

事务传播行为(propagation)的配置比如NOT_SUPPORTED等会导致事务失效,这些配置相当于给了他们配置的方法一个免死金牌,允许他们在加入标记为事务的方法后也不加入事务中而是单独存在,propagation就不细讲了,具体参考我ssm的文章

底层不支持

1.数据库引擎不支持事务,由于@Transactional只能保证Spring层面的事务逻辑,最终还是依赖于数据库引擎的支持,所以如果数据库引擎不支持事务,那@Transactional也会失效

2.多线程调用,若在事务方法中开启新线程执行数据库操作,新线程的操作不会纳入当前的事务管理,因为事务上下文无法跨线程传递

http://www.dtcms.com/a/545421.html

相关文章:

  • 【AI】Prompt 提示词工程
  • R语言高效数据处理-3个自定义函数笔记
  • 石家庄做网站备案有哪些公司品牌广告公司网站建设
  • 纯静态网站怎么入侵报告王妃
  • 郑州微盟网站建设公司网站建设的目的和目标
  • 仓颉中的字符串常用方法:语义一致性与高性能的设计哲学
  • 新MCU开发板快速上手指南:从开箱到精通
  • NestJS 项目创建
  • Apache Spark算法开发指导-特征转换-StandardScaler
  • 两个2的n次幂相加
  • 实时Java规范(RTSJ):从理论到实践的实时系统编程范式
  • 【Linux网络】进程间关系与守护进程
  • 建设部网站监理工程师报名wordpress菜单修改
  • vue 做网站 seo大连网站设计培训班
  • 【含文档+PPT+源码】基于SpringBoot和Vue的服装在线搭配及销售管理系统
  • 数据结构入门:深入理解顺序表与链表
  • 网站怎么做百度推广课题组网站怎么做
  • 前端React实战项目 全球新闻发布系统
  • 【React】 严格模式的 “双重执行” 机制,useEffect 执行两次
  • 使用 ngrok 在本地测试 Paddle Webhook 教程
  • React 入门 01:快速写一个React的HelloWorld项目
  • 地方旅游网站建设必要性网站怎么做站内美化
  • 设计网站栏目wordpress 三一重工
  • 黄冈网站建设策划海口建网站公司
  • 电子元器件学习-DC-DC篇:原理、拓扑结构、参数接收、手册解读、外围器件选型、Layout设计案例分析
  • SSD和HDD存储应该如何选择?
  • wordpress 博客 免费主题哈尔滨关键词优化方式
  • 河北网站排名网站内置字体
  • Yocto —— Linux Kernel 配置和修改
  • Rust结构体:数据组织的优雅范式与实例化实践