网站建设哪些字体没有版权阅读网站建设

web/2025/10/3 5:21:13/文章来源:
网站建设哪些字体没有版权,阅读网站建设,拼多多无货源电商怎么做,潍坊网站建设 世纪环球16楼1.概述 接着之前我们对Spring AOP以及基于AOP实现事务控制的上文#xff0c;今天我们来看看平时在项目业务开发中使用声明式事务Transactional的失效场景#xff0c;并分析其失效原因#xff0c;从而帮助开发人员尽量避免踩坑。 我们知道 Spring 声明式事务功能提供了极其…1.概述 接着之前我们对Spring AOP以及基于AOP实现事务控制的上文今天我们来看看平时在项目业务开发中使用声明式事务Transactional的失效场景并分析其失效原因从而帮助开发人员尽量避免踩坑。 我们知道 Spring 声明式事务功能提供了极其方便的事务配置方式配合 Spring Boot 的自动配置大多数 Spring Boot 项目只需要在方法上标记 Transactional 注解即可一键开启方法的事务性配置。当然后端开发人员对数据库事务这个概念并不陌生也知道如果整体考虑多个数据库操作要么成功要么失败时需要通过数据库事务来实现多个操作的一致性和原子性。如下所示 OverrideTransactional(rollbackFor Exception.class)public void addUser(UserParam param) {User user PtcBeanUtils.copy(param, User.class);userDAO.insert(user);if (!CollectionUtils.isEmpty(param.getRoleIds())) {userRoleService.addUserRole(user.getId(), param.getRoleIds());}}新增用户的同时还添加了用户角色这里就是使用Transactional来控制事务保证一致性的。但大多数开发仅限于为方法标记 Transactional来开启声明式事务认为就可以高枕无忧了不会去关注事务是否有效、出错后事务是否正确回滚也不会考虑复杂的业务代码中涉及多个子业务逻辑时怎么正确处理事务。事务没有被正确处理一般来说不会过于影响正常流程也不容易在测试阶段被发现。但当系统越来越复杂、压力越来越大之后就会带来大量的数据不一致问题随后就是大量的人工介入查看和修复数据。 正是因为声明式事务Transactional使用简单所以很多开发人员不注重细节点但是Transactional条条框框还蛮多的可谓是细节点拉满如果不注意也不小心就会掉进坑里今天就让我们一起来了解使用细节把坑填平咯。 2.Transactional 话不多说先看看该注解定义 Target({ElementType.TYPE, ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) Inherited Documented public interface Transactional {AliasFor(transactionManager)String value() default ;AliasFor(value)String transactionManager() default ;Propagation propagation() default Propagation.REQUIRED;Isolation isolation() default Isolation.DEFAULT;int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;boolean readOnly() default false;Class? extends Throwable[] rollbackFor() default {};String[] rollbackForClassName() default {};Class? extends Throwable[] noRollbackFor() default {};String[] noRollbackForClassName() default {};}从上面看出Transactional既可以作用于类上也可以作用于方法上**作用于类表示所有该类的public**方法都配置相同的事务属性信息。接下来再看看其属性 propagation 设置事务的传播行为主要解决是A方法调用B方法时事务的传播方式问题的默认值为 Propagation.REQUIRED其他属性值信息如下 事务传播行为解释REQUIRED默认值A调用BB需要事务如果A有事务B就加入A的事务中如果A没有事务B就自己创建一个事务REQUIRED_NEWA调用BB需要新事务如果A有事务就挂起B自己创建一个新的事务SUPPORTSA调用BB有无事务无所谓A有事务就加入到A事务中A无事务B就以非事务方式执行NOT_SUPPORTSA调用BB以无事务方式执行A如有事务则挂起NEVERA调用BB以无事务方式执行A如有事务则抛出异常MANDATORYA调用BB要加入A的事务中如果A无事务就抛出异常NESTEDA调用BB创建一个新事务A有事务就作为嵌套事务存在A没事务就以创建的新事务执行 **isolation **事务的隔离级别默认值为 Isolation.DEFAULT。指定事务的隔离级别事务并发存在三大问题脏读、不可重复读、幻读/虚读。可以通过设置事务的隔离级别来保证并发问题的出现常用的是READ_COMMITTED 和REPEATABLE_READ isolation属性解释DEFAULT默认隔离级别取决于当前数据库隔离级别例如MySQL默认隔离级别是REPEATABLE_READREAD_UNCOMMITTEDA事务可以读取到B事务尚未提交的事务记录不能解决任何并发问题安全性最低性能最高READ_COMMITTEDA事务只能读取到其他事务已经提交的记录不能读取到未提交的记录。可以解决脏读问题但是不能解决不可重复读和幻读REPEATABLE_READA事务多次从数据库读取某条记录结果一致可以解决不可重复读不可以解决幻读SERIALIZABLE串行化可以解决任何并发问题安全性最高但是性能最低 **timeout **事务的超时时间默认值为 -1。如果超过该时间限制但事务还没有完成则自动回滚事务。 **readOnly**指定事务是否为只读事务默认值为 false为了忽略那些不需要事务的方法比如读取数据可以设置 read-only 为 true。 **rollbackFor**用于指定能够触发事务回滚的异常类型可以指定多个异常类型。 **noRollbackFor**抛出指定的异常类型不回滚事务也可以指定多个异常类型。 项目推荐基于SpringBoot2.x、SpringCloud和SpringCloudAlibaba企业级系统架构底层框架封装解决业务开发时常见的非功能性需求防止重复造轮子方便业务快速开发和企业技术栈框架统一管理。引入组件化的思想实现高内聚低耦合并且高度可配置化做到可插拔。严格控制包依赖和统一版本管理做到最少化依赖。注重代码规范和注释非常适合个人学习和企业使用 Github地址https://github.com/plasticene/plasticene-boot-starter-parent Gitee地址https://gitee.com/plasticene3/plasticene-boot-starter-parent 微信公众号Shepherd进阶笔记 交流探讨qunShepherd_126 3.Transactional失效场景、原因及修正方式 3.1 同一个类中的方法通过this调用导致失效 public void addUser(UserParam param) {User user PtcBeanUtils.copy(param, User.class);// 新增用户userDAO.insert(user);// 添加用户角色this.addUserRole(user.getId(), param.getRoleIds());log.info(执行结束了);}Transactional(rollbackFor Exception.class)public void addUserRole(Long userId, ListLong roleIds) {if (CollectionUtils.isEmpty(roleIds)) {return;}ListUserRole userRoles new ArrayList();roleIds.forEach(roleId - {UserRole userRole new UserRole();userRole.setUserId(userId);userRole.setRoleId(roleId);userRoles.add(userRole);});userRoleDAO.insertBatch(userRoles);throw new RuntimeException(发生异常咯);}执行#addUser()会发现事务控制失效发生异常事务并没有回滚用户和角色绑定都插入成功了。 这里我给出Transactional 生效原则 1必须通过代理过的类从外部调用目标方法才能生效. Spring 是通过 AOP 技术对方法进行增强实现事务控制的要调用增强过的方法必然是调用代理后的对象而这里this是原生对象并不是代理自然就没有事务控制了。 修正方式①将this换成代理的userService, 可以自己注入自己Resource private UserService userService当然也可以不用注入直接在Spring容器中获取userService这个bean ②将#addUser()方法开启事务即加上Transactional(rollbackFor Exception.class)这里本就该开启只是为了演示失效情况没加上因为在#addUser()里面有插入用户的操作涉及到事务的所以本要开启。当然如果#addUser()只是做一些判断、逻辑处理不涉及到数据库事务操作那么这样解决就显得有点不太合适而且容易导致另一种事务失效的情况即因为没有正确处理异常导致事务即便生效也不一定能回滚。 3.2 异常被catch“吃掉了”导致Transactional失效 如下所示 Transactional(rollbackFor Exception.class)public void addUser(UserParam param) {try {User user PtcBeanUtils.copy(param, User.class);// 完成一些逻辑处理.......// 添加用户角色this.addUserRole(user.getId(), param.getRoleIds());log.info(执行结束了);} catch (Exception e) {log.error(e.getMessage());}}Transactional(rollbackFor Exception.class)public void addUserRole(Long userId, ListLong roleIds) {if (CollectionUtils.isEmpty(roleIds)) {return;}ListUserRole userRoles new ArrayList();roleIds.forEach(roleId - {UserRole userRole new UserRole();userRole.setUserId(userId);userRole.setRoleId(roleId);userRoles.add(userRole);});userRoleDAO.insertBatch(userRoles);throw new RuntimeException(发生异常咯);}Transactional生效原则2只有异常传播出了标记了 Transactional 注解的方法事务才能回滚。之前我们总结过 基于AOP事务控制实现原理说过在 Spring的 TransactionAspectSupport 里有个 invokeWithinTransaction 方法里面就是处理事务的逻辑。可以看到只有捕获到异常才能进行后续事务处理 protected Object invokeWithinTransaction(Method method, Nullable Class? targetClass,final InvocationCallback invocation) throws Throwable {......try {// This is an around advice: Invoke the next interceptor in the chain.// This will normally result in a target object being invoked.retVal invocation.proceedWithInvocation();}catch (Throwable ex) {// target invocation exception// 捕获到异常进行回滚操作如果我们在业务方法已经捕获掉异常这里就捕获不到了自然就不会回滚了completeTransactionAfterThrowing(txInfo, ex);throw ex;}finally {cleanupTransactionInfo(txInfo);}......return result;}}可以看到只有捕获到异常时才进行回滚操作如果我们在业务方法已经捕获掉异常这里就捕获不到了自然就不会回滚了。 修正方式就是对异常捕获尽量做到局部针对操作不要笼统把整个方法的代码逻辑都包括进行这样异常就抛出去了。 3.3 Transactional 属性 rollbackFor 设置错误导致异常不满足回滚条件 直接看代码 Transactionalpublic void addUser(UserParam param) {User user PtcBeanUtils.copy(param, User.class);.......// 添加用户角色this.addUserRole(user.getId(), param.getRoleIds());log.info(执行结束了);}public void addUserRole(Long userId, ListLong roleIds) throws Exception {if (CollectionUtils.isEmpty(roleIds)) {return;}ListUserRole userRoles new ArrayList();roleIds.forEach(roleId - {UserRole userRole new UserRole();userRole.setUserId(userId);userRole.setRoleId(roleId);userRoles.add(userRole);});userRoleDAO.insertBatch(userRoles);throw new Exception(发生异常咯);}这里#addUser()使用transactional但没有设置rollbackFor属性且#addUserRole()抛出的异常是exception不是RuntimeException这样事务也失效了因为默认情况下出现 RuntimeException非受检异常或 Error 的时候Spring才会回滚事务 从上面3.2小节的completeTransactionAfterThrowing(txInfo, ex);进去完成回滚操作会判断异常类型是否满足规定DefaultTransactionAttribute 类能看到如下代码块可以发现相关证据通过注释也能看到 Spring 这么做的原因大概的意思是受检异常一般是业务异常或者说是类似另一种方法的返回值出现这样的异常可能业务还能完成所以不会主动回滚而Error 或 RuntimeException 代表了非预期的结果应该回滚 public boolean rollbackOn(Throwable ex) {return (ex instanceof RuntimeException || ex instanceof Error);}修正方法设置rollbackForTransactional(rollbackFor Exception.class) 3.4 Transactional 应用在非 public 修饰的方法上 Transactional(rollbackFor Exception.class)private void addUserRole(Long userId, ListLong roleIds) {if (CollectionUtils.isEmpty(roleIds)) {return;}ListUserRole userRoles new ArrayList();roleIds.forEach(roleId - {UserRole userRole new UserRole();userRole.setUserId(userId);userRole.setRoleId(roleId);userRoles.add(userRole);});userRoleDAO.insertBatch(userRoles);throw new RuntimeException(发生异常咯);}idea也会提示爆红 Spring通过CGLIB动态代理来增强生产代理对象CGLIB 通过继承方式实现代理类private 方法在子类不可见自然也就无法进行事务增强。s在基于AOP事务控制实现原理一文中也分析过会调用到AbstractFallbackTransactionAttributeSource的computeTransactionAttribute()方法 Nullableprotected TransactionAttribute computeTransactionAttribute(Method method, Nullable Class? targetClass) {// Dont allow no-public methods as required.if (allowPublicMethodsOnly() !Modifier.isPublic(method.getModifiers())) {return null;}......}修正方式自然是改成public 3.5 Transactional 注解传播属性 propagation 设置错误 如上面我们新增的用户的同时要添加用户角色但是假如我们希望即使添加角色错误了还可以正常新增用户。 public void addUser(UserParam param) {String username param.getUsername();checkUsernameUnique(username);User user PtcBeanUtils.copy(param, User.class);// 添加用户userDAO.insert(user);// 添加用户角色userRoleService.addUserRole(user.getId(), param.getRoleIds());}#userRoleService.addUserRole() Transactional(rollbackFor Exception.class)private void addUserRole(Long userId, ListLong roleIds) {if (CollectionUtils.isEmpty(roleIds)) {return;}ListUserRole userRoles new ArrayList();roleIds.forEach(roleId - {UserRole userRole new UserRole();userRole.setUserId(userId);userRole.setRoleId(roleId);userRoles.add(userRole);});userRoleDAO.insertBatch(userRoles);throw new RuntimeException(发生异常咯);}你会发现只会同时插入失败无法实现上面所说的。这时候你可能会想到既然addUserRole()抛出了异常不能插入用户角色但是addUser()不想受影响正常添加用户那么何不在addUser()里面对userRoleService.addUserRole()进行异常捕获不就可以解决问题了吗真是如此吗就让我们来验证一下 Transactional(rollbackFor Exception.class)public void addUser(UserParam param) {User user PtcBeanUtils.copy(param, User.class);// 添加用户userDAO.insert(user);// 添加用户角色try {userRoleService.addUserRole(user.getId(), param.getRoleIds());} catch (Exception e) {log.error(e.getMessage());}}执行会发现用户同样没有添加成功看日志报错 [1689568520410750976] [ERROR] [2023-08-10 17:25:02.023] [http-nio-18888-exec-156682] com.plasticene.fast.service.impl.UserServiceImpl addUser : 发生异常咯 [1689568520410750976] [ERROR] [2023-08-10 17:25:02.097] [http-nio-18888-exec-156682] com.plasticene.boot.web.core.global.GlobalExceptionHandler exceptionHandler : 【系统异常】 org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-onlyat org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:870)可以看到发生异常咯是我们在addUser()中捕获到输出的但是紧接着下一行发现有报出一个异常UnexpectedRollbackException。 原因是主方法添加用户的逻辑和子方法添加用户角色的逻辑是同一个事务子逻辑标记了事务需要回滚主逻辑自然也不能提交了。 修正方式其实要想新增用户角色失败不影响添加用户只需要让新增用户角色单独开启一个新事务即可。 Transactional(rollbackFor Exception.class, propagation Propagation.REQUIRES_NEW)public void addUserRole(Long userId, ListLong roleIds) {ListUserRole userRoles new ArrayList();roleIds.forEach(roleId - {UserRole userRole new UserRole();userRole.setUserId(userId);userRole.setRoleId(roleId);userRoles.add(userRole);});userRoleDAO.insertBatch(userRoles);throw new RuntimeException(发生异常啦);}3.6 Transactional长事务导致生产事故 很多开发都觉得Spring的声明式事务使用非常简单即Transactional所以从来不注重细节。当 Spring 遇到该注解时会自动从数据库连接池中获取 connection并开启事务然后绑定到 ThreadLocal 上对于Transactional注解包裹的整个方法都是使用同一个connection连接。如果我们出现了耗时的操作比如第三方接口调用、业务逻辑复杂、大批量数据处理等就会导致我们我们占用这个connection的时间会很长数据库连接一直被占用不释放。一旦类似操作过多就会导致数据库连接池耗尽。这就是典型的长事务问题 长事务引发的常见危害有 数据库连接池被占满应用无法获取连接资源容易引发数据库死锁数据库回滚时间长在主从架构中会导致主从延时变大。 服务系统开始出现故障数据库监控平台一直收到告警短信数据库连接不足出现大量死锁日志显示调用流程引擎接口出现大量超时同时一直提示CannotGetJdbcConnectionException数据库连接池连接占满。 要想解决这个问题其实也不难只需要对方法进行拆分将不需要事务管理的逻辑与事务操作分开这样就可以有效控制事务的时长从而避免长事务。当然对一个方法逻辑拆分成多个子方法很有可能造成上面叙述的事务不生效的情况不过我相信你看到上面的总结肯定没问题啦。 4.总结 Spring的声明式事务使用Transactional注解在开发时确实很方便但是稍有不慎使用不当就会导致事务失效数据不一致、甚至是系统数据库性能问题。所以上面满满的干货总结都是出自日常工作中碰到的有效帮你避坑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/86031.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

外贸企业网站源码下载创新的成都网站建设

为什么80%的码农都做不了架构师?>>> 1、公司项目需求。 用户签到活动,会员签到怎么处理,超级会员怎么处理,普通用户签到怎么处理,针对不同的档次,有不同的方案,所以在项目中用到了策…

墓地网站建设价格wordpress即阅文教程

2019独角兽企业重金招聘Python工程师标准>>> 首先在win7上安装nc命令 下载nc程序包,放在c盘目录下,cmd打开命令行,进入nc目录,执行:nc -l -L -p 8888开始监控。再打开一个命令行窗口进入nc目录,…

如何做众筹网站泉州百度推广咨询

源宝导读:“业务模板”作为天际建模平台3.0推出的重要特性,它将元数据复用发挥到了极致,通过业务模板几乎可以覆盖整个建模元数据开发流程,提供业务场景级别的复用能力。本文将介绍“业务模板”的设计原理、实现方案和应用场景。一…

萍乡网站建设公司网页图片大全

详见 集成测试,单元测试隔离 maven-surefire-plugin maven的goal生命周期 Maven生存周期 - 含 integration-test Maven本身支持的命令(Goals)是有顺序的,越后面执行的命令,会将其前面的命令和其本身按顺序执行一遍,…

网站建设化学图片哪些网站需要备案

1. 为什么要用缓存? 用缓存,主要有两个用途:高性能、高并发。 高性能 假设这么个场景,你有个操作,一个请求过来,吭哧吭哧你各种乱七八糟操作 MySQL,半天查出来一个结果,耗时 600m…

移动网站建设成都市青羊区建设局官方网站

忙碌了一周,一直没时间更新,趁着周末来更新第二个题目。 题目 题目解析 这个题目相比于上一个题目来说,会简单一些,不涉及到那些复杂的算法,就是对于字符串的处理。 算法步骤 输入一个字符串根据分号,将…

河南中安建设集团有限公司网站泗水做网站

ROS元功能包(Metapackage)是一种特殊的软件包,它本身并不包含任何可执行代码或数据文件。在ROS 1中,可以通过catkin_create_pkg命令创建元功能包。 相反,它的主要目的是作为一组相关功能包的集合或者依赖关系列表。使…

单页销售网站如何赚钱推荐10个网站

打开重要的Excel文件时遇到问题吗?Microsoft Excel是否要求你验证文件是否已损坏?Excel文件可能由于各种原因而损坏,从而无法打开。但不要失去希望;你可以轻松修复损坏的Excel文件。 更改Excel信任中心设置 Microsoft Excel有一个内置的安全功能,可以在受限模式下打开有…

学校网站建设计划网页微信客户端手机版

目录 说明: 1. 电路组成 2. 逻辑功能 3. 特性表 4. 特性方程 5. 例题 6. 两种基本RS触发器的形式比 说明: 笔记配套视频来源:B站;本系列笔记并未记录所有章节,只对个人认为重要章节做了笔记;标题前…

手机端网站开发流程图wordpress安装到虚机

一、Dispatch Queue挂起dispatch queue可以被挂起和恢复。使用 dispatch_suspend函数来挂起,使用 dispatch_resume 函数来恢复。这两个函数的行为是如你所愿的。另外,这两个还是也可以用于dispatch source。一个要注意的地方是,dispatch que…

谷歌应用商店app下载seo网站关键词优化费用

本文主要是关于汇编和 C 语言的相关介绍,并着重对汇编和 C 语言的不同及其编程技巧进行了详尽的阐述。汇编和 C 语言C 语言和汇编语言的区别在于他们之间优缺点几乎是相反的。C 语言和汇编语言的优缺点:以 c 来举例优点:c 的运行效率高&#…

中铁建设中南公司官方网站重庆网站推广产品

鸿蒙linux内核的L1设备服务开发详解 ​ 鸿蒙基于linux内核的L1设备的系统基于面向服务架构,提供了服务开发、服务的子功能开发、对外接口的开发、以及多服务进程、进程间服务调用的开发能力。现对此基座下的服务进行剖析并以实例方式进行讲解。 一、简介 在L1设备…

沭阳网站建设托管wordpress163邮件

现在最火的后端架构无疑是微服务了,微服务将之前的单体应用拆分成了许多独立的服务应用,每个微服务都是独立的,好处自然很多,但是随着应用的越来越大,微服务暴露出来的问题也就随之而来了,微服务越来越多&a…

公司做网站找谁做网站的公司阿里云万网网站制作

Linux ncftp命令介绍 ncftp是一种增强的FTP客户端程序,它可以让你在本地和远程服务器之间传输文件,并管理远程服务器上的文件和目录。ncftp具有许多特色,包括显示传输速率,下载进度,自动续传,标记书签&…

网站开发洲际个人网站主办者名称

来源:神经科技概要:近二十年来,基于静息态功能磁共振影像的人脑连接组学快速发展,为无创研究活体人脑的功能组织规律和网络运作机制提供了重要手段,大大促进了研究者对脑认知、脑发育和脑疾病神经机制的理解。近日&…

建设一个网站成本多少钱中英文对照网站怎么做

引言:性能瓶颈调优 在实际的性能测试中,会遇到各种各样的问题,比如 TPS 压不上去等,导致这种现象的原因有很多,测试人员应配合开发人员进行分析,尽快找出瓶颈所在。 理想的性能测试指标结果可能不是很高&…

网站数据流程h5 和手机网站

开篇:探索稀疏多视图图像的3D场景重建与新视角合成的挑战 3D场景重建和新视角合成是计算机视觉领域的一项基础挑战,尤其是当输入图像非常稀疏(例如,只有两张)时。尽管利用神经场景表示,例如场景表示网络&a…

做公益网站的原因做电商网站的设计思路有什么意思

Three场景实现多个物体的合并 目的 产品需求是让物体的光柱墙包含一个多边形的区域,二而我的多边形只能使用原型,方向,多边形。那么再研究的时候就需要将这些多边形合并成为一个形状,那么就行实现了。 原先的图形 如上图,是两个mesh组成的。首先寻找mesh合并的方法。 第…

深圳住房网站app北京网络职业学院怎么样

1. 数学研究 1.1. 数学研究变得更为艰难了 1.1.1. 学科分支越发密集,问题越发复杂 1.1.2. 攻读博士学位的3年时间,只够去理解导师所给题目的含义 1.1.3. 随后,再花费数年时间去研究、探索,运气不错的话,会得到一些…

梅州市建设局网站素材中国官网

微信小程序css 华文琥珀Brian Goetz最近的消息欢迎来到琥珀! 介绍Project Amber ( OpenJDK的一部分, 最初于1月提出 )。 Goetz通过介绍“欢迎使用Amber项目,这是我们面向特定生产力的Java语言JEP的孵化场”的介绍打开了…