免费网站软件推荐seo搜索引擎优化公司
- 作者: 五速梦信息网
- 时间: 2026年03月21日 10:23
当前位置: 首页 > news >正文
免费网站软件推荐,seo搜索引擎优化公司,黄页号码怎么查,安庆注册公司目录 一、什么是事务#xff0c;为什么要用事务 二、Spring声明式事务 #x1f345; 1、Transactional的使用 #x1f388; 事务回滚 #x1f388;注意#xff1a;异常被捕获#xff0c;不会发生事务回滚 #x1f345; 2、Transactional 作⽤范围 #x1f345; …目录 一、什么是事务为什么要用事务 二、Spring声明式事务 1、Transactional的使用 事务回滚 注意异常被捕获不会发生事务回滚 2、Transactional 作⽤范围 3、Transactional 参数说明 4、Transactional的工作原理 三、事务的特性以及隔离级别重要 事务的特性ACID Spring隔离级别 四、Spring事务的传播机制 为什么需要事务传播机制 事务传播机制的种类 Propagation.REQUIRED Propagation.SUPPORTS Propagation.NEVER Propagation.NESTED 一、什么是事务为什么要用事务 定义事务就是将一组操作封装成一个执行单元封装到一起要么全部成功要么全部失败 为什么要用事务举例如下 转账分为两步 第一步A账户-100 第二部B账户100 如果没有事务那么第一步执行成功第二部失败就会导致100不见了不知道转哪里去了。但是当有了事务着两步操作要么一起成功要么一起失败这样就可以解决这个问题 分类Spring中的事务操作分为两类 编程式事务手动写代码操作事务不常用复杂声明式事务利用注解自动开启和提交事务常用简便 下面主要介绍声明式事务 二、Spring声明式事务 1、Transactional的使用 事务回滚 声明式事务的使用很简单只需要在方法上添加Transactional注解就可以实现了 不需要手动开启事务和提交事务进入方法时自动开启事务方法执行完就会自动提交事务如果中途发生了没有处理的异常就会自动回滚事务。 代码示例 Data public class UserInfo {private int id;private String username;private String password;private String photo;private LocalDateTime createtime;private LocalDateTime updatetime;private int state; } Mapper public interface UserMapper {Insert(insert into userinfo(username,password) values (#{username},#{password}))int add(UserInfo userInfo); } Service public class UserService {Autowiredprivate UserMapper userMapper;public int add(UserInfo userInfo){return userMapper.add(userInfo);} } RequestMapping(/user) RestController public class UserController {Autowiredprivate UserService userService;RequestMapping(/add)Transactionalpublic int add(){ // 1.非空判断UserInfo userInfo new UserInfo();userInfo.setUsername(huhu);userInfo.setPassword(123); // 2.调用service执行添加int result userService.add(userInfo);System.out.println(result result);int num 10⁄0; // 3.将结果给前端return result;} } 执行以上代码结果如下发生算数异常 但是sql执行没有异常 这时候我们查看以下数据库有没有该数据有没有进行数据回滚 图中并没有我添加的数据由此可见Transactional注解进行了数据回滚。 注意异常被捕获不会发生事务回滚 问题当自己把程序捕获以后代表着事务不会发现程序发生了异常在这种情况下事务不会发生回滚。 RequestMapping(/add)Transactionalpublic int add(){ // 1.非空判断UserInfo userInfo new UserInfo();userInfo.setUsername(huhu);userInfo.setPassword(123); // 2.调用service执行添加int result userService.add(userInfo);System.out.println(result result);try{int num 10⁄0;}catch (Exception e){} // 3.将结果给前端return result;} 解决方案1 将异常继续抛出去代理对象就能感知到异常也能够回滚到事务 RequestMapping(/add)Transactionalpublic int add(){ // 1.非空判断UserInfo userInfo new UserInfo();userInfo.setUsername(万叶);userInfo.setPassword(123); // 2.调用service执行添加int result userService.add(userInfo);System.out.println(result result);try{int num 10⁄0;}catch (Exception e){throw e;} // 3.将结果给前端return result;} 新增的信息不在里面万叶的信息 解决方案2使用代码手动回滚事务 RequestMapping(/add)Transactionalpublic int add(){ // 1.非空判断UserInfo userInfo new UserInfo();userInfo.setUsername(万叶);userInfo.setPassword(123); // 2.调用service执行添加int result userService.add(userInfo);System.out.println(result result);try{int num 10⁄0;}catch (Exception e){TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();} // 3.将结果给前端return result;} 2、Transactional 作⽤范围 Transactional 可以用来修饰类或者方法public 修饰方法时只能应用到public方法上面否则不生效修饰类时表明该注解对该类的所有public方法都生效 3、Transactional 参数说明 一般情况下以下参数都是默认的 4、Transactional的工作原理 Transactional是基于AOP实现的AOP又是基于动态代理实现的。 如果目标对象实现了接口默认情况下就会采用JDK的动态代理如果目标对象没有实现接口会使用CGLIB的动态代理。 Transactional在开始执行业务之前通过代理先开始事务在执行成功之后再提交事务。如果中途遇见异常则回滚事务。 Transactional实现思路预览 Transactional具体执行细节如下图所示 三、事务的特性以及隔离级别重要 脏读一个事务读取到了另一个事务修改的数据以后后一个事务又进行了回滚操作从而导致第一个事务读取到的数据是错误的。 不可重复读一个事务两次查询得到的结果不同因为在两次查询中间有另一个事务把数据修改了 幻读一个事务两次查询中得到的结果集不同因为在两次查询中另一个事务又新增了一部分数据。 事务的特性ACID 原子性不可分割性Atomicity一个事务中的所有操作要么全部完成要么全部不完成不会结束中间某个环节。事务在执行过程中发生错误就会回滚到事务开始前的状态相当这个事务从来没有执行过 一致性Consistency在事务开始之前和事务结束以后数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则包含资料的精确度、串联性以及后续数据库可以自发性的完成预定的工作。 持久性Isolation事务处理结束以后对数据的修改就是永久的即便系统故障也不会丢失 隔离性Durability数据库允许多个并发事务同时对齐数据进行读写和修改的能力隔离性可以放置多个事务并发执行时由于交叉执行导致数据的不一致。事务的隔离分为不同级别包括读未提交读提交可重复读串行化。 Spring隔离级别 Spring事务隔离级别有五种 Isolation.DEFAULT以连接的数据库的事务隔离级别为主 Isolation.READ_UNCOMMITTED读未提交可以读取到未提交的事务存在脏读 Isolation.READ_COMMITTED读已提交只能读取到已经提交的事务解决了脏读存在不可重复度。 Isolation.REPEATABLE_READ可重复读解决了不可重复度但是存在幻读。 Isolation.SERIALIZABLE串行化可以解决所有并发问题但是性能太低。 默认情况下是以SQL的事务隔离级别为主的Isolation.DEFAULT。 但是当Sping设置了事务隔离级别以后就会以Spring的事务隔离级别为主。以下就是以SERIALIZABLE为主的。 RequestMapping(/add)Transactional(isolation Isolation.SERIALIZABLE)public int add(){ }事务的隔离级别保证了多个并发事务执行的可控性。 四、Spring事务的传播机制 定义事务的传播机制定义了多个包含事务的方法相互调用时事务是如何在这些方法间进行传递的。规定多个事务在相互调用时事务的执行行为 为什么需要事务传播机制 事务传播机制是保证一个事务在多个调用方法间的可控性的稳定性 事务的传播机制解决的是一个事务在多个节点方法中传递的问题 事务传播机制的种类 Propagation.REQUIRED默认的事务传播级别表示如果当前存在事务则加入该事务如果当前没有事务则创建一个新的事务 Propagation.SUPPORTS如果当前存在事务则加入该事务如果当前没有事务则以非事务的方式继续运行 Propagation.MANDATORY如果当前存在事务则加入该事务如果当前没有事务则抛出异常 Propagation.REQUIRES_NEW表示创建一个新的事务如果当前存在事务则把当前事务挂起。也就是说不管外部方法是否开启事务Propagation.REQUIRES_NEW修饰的内部方法会新开启自己的事务且开启的事务相互独立互不干扰。 Propagation.NOT_SUPPORTED以非事务方式运行如果当前存在事务则把当前事务挂起 Propagation.NEVER以非事务方式运行如果当前存在事务则抛出异常 Propagation.NESTED如果当前存在事务则创建一个事务作为当前事务的嵌套事务来运行如果当前没有事务则该取值等价于Propagation.REQUIRED Propagation.REQUIRED 默认的事务传播级别表示如果当前存在事务则加入该事务如果当前没有事务则创建一个新的事务 示例 UserService: Transactionalpublic int add(UserInfo userInfo){int result userMapper.add(userInfo);System.out.println(add result - result);insert(userInfo);return result;}Transactionalpublic int insert(UserInfo userInfo){int result userMapper.add(userInfo);System.out.println(insert resullt - result);int num 10 / 0;return result;} Controller: RequestMapping(/add)Transactional(propagation Propagation.REQUIRED)public int add(){ // 1.非空判断UserInfo userInfo new UserInfo();userInfo.setUsername(万叶);userInfo.setPassword(123); // 2.调用service执行添加int result userService.add(userInfo);return result;} 此时结果是报错是算数异常进行了事务回滚数据库中没有添加任何数据 Propagation.SUPPORTS 如果当前存在事务则加入该事务如果当前没有事务则以非事务的方式继续运行 示例 UserService Transactional(propagation Propagation.SUPPORTS)public int add(UserInfo userInfo){int result userMapper.add(userInfo);System.out.println(add result - result);insert(userInfo);return result;}Transactional(propagation Propagation.SUPPORTS)public int insert(UserInfo userInfo){int result userMapper.add(userInfo);System.out.println(insert resullt - result);int num 10 / 0;return result;} UserController: Transactional(propagation Propagation.SUPPORTS)public int add(){ // 1.非空判断UserInfo userInfo new UserInfo();userInfo.setUsername(万叶);userInfo.setPassword(123); // 2.调用service执行添加int result userService.add(userInfo);return result;} 当前调用链不存在事务结果是数据库中添加了两条数据并且报错是算数异常但是并没有进行数据回滚 Propagation.NEVER 以非事务方式运行如果当前存在事务则抛出异常 UserController: RequestMapping(/add) //调用链存在事务Transactional(propagation Propagation.REQUIRED)public int add(){ // 1.非空判断UserInfo userInfo new UserInfo();userInfo.setUsername(万叶);userInfo.setPassword(123); // 2.调用service执行添加int result userService.add(userInfo);return result;} USerService: Transactional(propagation Propagation.NEVER)public int add(UserInfo userInfo){int result userMapper.add(userInfo);System.out.println(add result - result);insert(userInfo);return result;}Transactional(propagation Propagation.NEVER)public int insert(UserInfo userInfo){int result userMapper.add(userInfo);System.out.println(insert resullt - result);int num 10 / 0;return result;} 说明程序在发现有事务以后就没有运行了不存在事务回滚而是发现事务以后程序就没有运行而是直接抛出异常。 Propagation.NESTED 如果当前存在事务则创建一个事务作为当前事务的嵌套事务来运行如果当前没有事务则该取值等价于Propagation.REQUIRED 示例 UserService: 注意为什么要try-catch 如果不try-catch就会报错报错就会使得整个程序进行回滚这里为了使得满足NESTED的情况就进行了try-catch就能使得回滚到事务保存点。 Transactional(propagation Propagation.NESTED)public int add(UserInfo userInfo){int result userMapper.add(userInfo);System.out.println(add result - result);return result;}Transactional(propagation Propagation.NESTED)public int insert(UserInfo userInfo){int result userMapper.add(userInfo);System.out.println(insert resullt - result);try{int num 10 / 0;}catch (Exception e){TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}return result;} UserController RequestMapping(/add)Transactional(propagation Propagation.REQUIRED)public int add(){ // 1.非空判断UserInfo userInfo new UserInfo();userInfo.setUsername(影);userInfo.setPassword(123); // 2.调用service执行添加int result userService.add(userInfo);userService.insert(userInfo);return result;} 结果如下
- 上一篇: 免费网站排名优化vi设计基础部分都有哪些
- 下一篇: 免费网站设计神器邮箱注册网站
相关文章
-
免费网站排名优化vi设计基础部分都有哪些
免费网站排名优化vi设计基础部分都有哪些
- 技术栈
- 2026年03月21日
-
免费网站能到百度首页吗推广app赚佣金平台有哪些
免费网站能到百度首页吗推广app赚佣金平台有哪些
- 技术栈
- 2026年03月21日
-
免费网站模板之家2345官网
免费网站模板之家2345官网
- 技术栈
- 2026年03月21日
-
免费网站设计神器邮箱注册网站
免费网站设计神器邮箱注册网站
- 技术栈
- 2026年03月21日
-
免费网站申请域名淮安软件园网站建设
免费网站申请域名淮安软件园网站建设
- 技术栈
- 2026年03月21日
-
免费网站申请注册无锡做食品网站的公司简介
免费网站申请注册无锡做食品网站的公司简介
- 技术栈
- 2026年03月21日
