做暖暖免费视频网站哪些人做数据监测网站
web/
2025/10/1 4:00:33/
文章来源:
做暖暖免费视频网站,哪些人做数据监测网站,字体设计网站有哪些,网站建设招标方式目录
事务基本概念
前置准备
Spring Boot 事务使用
编程式事务
声明式事务
Transactional 注解参数说明
Transational 对异常的处理
解决方案一
解决方案二
Transactional 的工作原理
面试题
Spring Boot 事务失效的场景有那些#xff1f; 事务基本概念 事务指一…目录
事务基本概念
前置准备
Spring Boot 事务使用
编程式事务
声明式事务
Transactional 注解参数说明
Transational 对异常的处理
解决方案一
解决方案二
Transactional 的工作原理
面试题
Spring Boot 事务失效的场景有那些 事务基本概念 事务指一组操作这些操作要么全部成功要么全部失败如果在一组操作中有一个操作失败了那么整个事务便会回滚即撤销已经执行的操作从而保证数据的一致性和完整性 实例理解 典型实际场景为 银行转账操作 两个步骤 从源账户扣除指定金额将该金额添加到目标账户 分析原因 这两个步骤必须保证同时执行成功如果其中任意一个步骤失败便必须撤销整个操作以保持数据的一致性即 在扣款成功后如果存款时发生错误如网络问题那么我们必须要回滚扣款操作以确保不会错误地从源账户中扣款 前置准备 下述实例均基于 实现根据用户 id 删除用户信息功能 创建一个 user 表并添加几条用户信息 创建 User 实体类 与 数据库的 user 表字段名相对应 import lombok.Data;Data
public class User {private int id;private String name;private int age;private String password;private int state;
} 初始化 UserMapper 接口此处我们添加一个 del 方法 import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;//添加 Mapper 注解 代表该接口会伴随这 项目的启动而注入到容器中
Mapper
public interface UserMapper {// 根据用户id 删除用户信息int del(Param(user_id) int id);
} 在与 接口相对应的 XML 文件中添加上与 del 方法 相对应的 sql 语句 ?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.example.demo.mapper.UserMapperdelete iddeldelete from user where id #{user_id}/delete
/mapper Spring Boot 事务使用 编程式事务 Spring Boot 中内置了两个对象DataSourceTransactionManager 用来获取事务开启事务、提交或回滚事务TransactionDefinition 为事务的属性在获取事务的时候需要将其 传递进去从而获得一个事务 TransactionStatus 实例理解 我们在 UserController 中 使用编程式事务给 根据用户id 删除用户信息 这一功能加上事务 import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;ResponseBody
Controller
RequestMapping(/user)
public class UserController {Autowiredprivate UserService userService;// 编程式 事务Autowiredprivate DataSourceTransactionManager transactionManager;Autowiredprivate TransactionDefinition transactionDefinition;RequestMapping(/del)public String del(Integer id) {if(id 0 || id null) return 请输入正确的用户 id;TransactionStatus transactionStatus null;int result 0;try {
// 1. 开启事务transactionStatus transactionManager.getTransaction(transactionDefinition);
// 2. 业务操作 删除用户result userService.del(id);System.out.println(del 方法 (result 1 ? 删除成功: 删除失败 ));
// 3. 提交事务transactionManager.commit(transactionStatus); // 提交事务}catch (Exception e) {if(transactionStatus ! null){
// 发生异常 回滚事务transactionManager.rollback(transactionStatus); // 回滚事务}}return del 方法 (result 1 ? 删除成功: 删除失败 );}
}测试结果 在浏览器的 URL 地址框中输入相对应地址来调用上述代码的方法 声明式事务 Spring Boot 提供了 Transactional 注解实现事务只需在需要的方法上添加 Transaction 注解即可无需手动开启事务和提交事务进入方法时自动开启事务方法执行完会自动提交事务如果中途发生了没有处理的异常会自动回滚事务 注意 Transactional 注解可以用来修饰方法或类修饰方式时该方法必须为 public 否则不生效修饰类时表明该注解对该类中所以的 public 方法都生效 实例理解 我们在 UserController2 中 使用声明式事务给 根据用户id 删除用户信息 这一功能加上事务 import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;RestController
RequestMapping(/user2)
public class UserController2 {Autowiredprivate UserService userService;RequestMapping(/del)Transactionalpublic String del(Integer id) {if(id 0 || id null) return 请输入正确的用户 id;int result userService.del(id);return del 方法 (result 1 ? 删除成功: 删除失败 );}
} 测试结果 在浏览器的 URL 地址框中输入相对应地址来调用上述代码的方法 Transactional 注解参数说明 参数作用value当配置了多个事务管理器时可以使用该属性指定选择哪个事务管理器transactionManager当配置了多个事务管理器时可以使用该属性指定选择哪个事务管理器propagation事务的传播行为默认值为 Propagation.REQUIREDisolation事务的隔离级别默认值为 Isolation.DEFAULTtimeout事务的超时时间默认值为 -1 如果超过该事件限制但事务还没有完成则自动回滚事务readOnly指定事务是否为只读事务 默认值为 false 为了忽略那些不需要事务的方法 比如读取事务rollbackFor用于指定能够触发事务回滚的异常类型 可以指定多个异常类型rollbackForClassName用于指定能够触发事务回滚的异常类型 可以指定多个异常类型noRollbackFor抛出指定的异常类型不会滚事务也可以指定多个异常类型noRollbackForClassName抛出指定的异常类型不会滚事务也可以指定多个异常类型 注意 区别 只读事务 和 无事务只读事务 可以设置隔离级别默认为可重复读可设置 isolation 更改隔离级别无事务 仅为默认的隔离级别可重复读 Transational 对异常的处理 实例理解 此处我们故意在 UserController 中加入异常代码并手动捕获该 算数异常那么此处 Transational 是否会回滚 del 操作呢 package com.example.demo.controller;import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;RestController
RequestMapping(/user2)
public class UserController2 {Autowiredprivate UserService userService;RequestMapping(/del)Transactional // 在方法执行前开启事务 方法正常执行完后提交事务 执行途中发生异常回滚事务public String del(Integer id) {if(id 0 || id null) return 请输入正确的用户 id;int result userService.del(id);try {int num 10/0;} catch (Exception e) {e.printStackTrace();}return del 方法 (result 1 ? 删除成功: 删除失败 );}
}执行结果 在浏览器的 URL 地址框中输入相对应地址来调用上述代码的方法 由上图可知此处我们的 Transational 并未回滚 del 操作即 Transactional 在异常被捕获的情况下不会进行事务的自动回滚 解决方案一 捕获到异常后再重新抛出异常让框架感知到异常如果框架感知到异常便会自动回滚事务 RequestMapping(/del)
Transactional // 在方法执行前开启事务 方法正常执行完后提交事务 执行途中发生异常回滚事务public String del(Integer id) {if(id 0 || id null) return 请输入正确的用户 id;int result userService.del(id);try {int num 10/0;} catch (Exception e) {e.printStackTrace();
// 抛出异常throw e;}return del 方法 (result 1 ? 删除成功: 删除失败 );
} 执行结果 在浏览器的 URL 地址框中输入相对应地址来调用上述代码的方法 数据库中 id 1 的 xiaolin 未被删除说明此时 Transational 进行了回滚操作 解决方案二 捕获到异常后手动回滚事务此处框架是感知不到异常的 RequestMapping(/del)
Transactional // 在方法执行前开启事务 方法正常执行完后提交事务 执行途中发生异常回滚事务public String del(Integer id) {if(id 0 || id null) return 请输入正确的用户 id;int result userService.del(id);try {int num 10/0;} catch (Exception e) {e.printStackTrace();
// 手动回滚事务TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}return del 方法 (result 1 ? 删除成功: 删除失败 );
} TransactionAspectSupport 为 Spring 框架中的一个类提供了事务相关的支持和功能currentTransactionStatus 为 TransactionAspectSupport 类的一个静态方法用于获取当前事务的状态对象setRollbackOnly 为 TransactionStatus 接口的一个方法用于将当前事务标记为回滚状态0 执行结果 在浏览器的 URL 地址框中输入相对应地址来调用上述代码的方法 数据库中 id 1 的 xiaolin 未被删除说明此时 Transational 进行了回滚操作 重点理解 此处为什么会返回一个 删除成功代码从上到下顺序执行先执行了 del 操作即此处的 result 值已经成功被赋值为 1 返回值为 del 操作影响的行数然后我们才对 算数异常进行捕获捕获之后再进行的 回滚操作且异常捕获之后我们并未抛出异常从而不会出现方案一的服务器错误在捕获完异常后代码将继续向下执行此时便返回 del 方法 (result 1 ? 删除成功: 删除失败 )因为此处的 result 等于 1所以返回了一个 删除成功但是我们要明白的是 我们在捕获异常后在处理异常时进行了事务的回滚所以此处数据库中的 id 1 的 xiaolin 未被删除 Transactional 的工作原理 此处声明式事务的实现方式 可使用 Spring AOP 来实现执行目标方法之前 先开启事务类似于前置通知执行完目标方法之后 再提交事务类似于后置通知如果在执行中途发生了没有处理的异常 便回滚事务综上 我们可以直接将目标方法 写入环绕通知中 /*
* 环绕通知
* 此处的 joinPoint 就是连接点即方法本身
* */
Around(pointcut())
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {Object obj null;System.out.println(执行目标方法之前 这里开启事务);try {
// 此处执行目标方法obj joinPoint.proceed();}catch (Exception e) {System.out.println(执行目标方法出现异常 这里回滚事务);}System.out.println(执行目标方法之后 这里提交事务);
// 最后将执行的结果交给框架return obj;
} 上述代码仅为 实现声明式事务 的大致思路 面试题 Spring Boot 事务失效的场景有那些 Transactional 修饰的方法为非 public 导致事务失效Transactional 设置了一个较小的超时时间如果方法本身的执行时间超过了设置的 timeout 超时时间那么就会导致本来应该正常插入数据的方法执行失败代码中有 try/catch 语句仅捕获异常不进行额外处理则导致 Transactional 不会自动回滚事务数据库不支持事务我们程序中的 Transactional 只是给调用的数据库发生了开始事务、提交事务 或 回滚事务 的之类但是如果数据库本身不支持事务如 MySQL 中设置了使用 MySAM 引擎那么它本身是不支持事务的在这种情况下即使在程序中添加了 Transactional 注解那么依然不会有事务行为当调用类内部的 Transactional 修饰的方法时事务是不会生效的 RequestMapping(/save)
public int saveMappping(UserInfo userInfo) {return save(userInfo);
}
Transactional
public int save(UserInfo userInfo) {// 非空效验if (userInfo null ||!StringUtils.hasLength(userInfo.getUsername()) ||!StringUtils.hasLength(userInfo.getPassword()))return 0;int result userService.save(userInfo);int num 10 / 0; // 此处设置一个异常return result;
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/84835.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!