Spring-声明式事务实例(有详细注释)

前提知识

Spring-IOC容器注解方式使用icon-default.png?t=N7T8https://blog.csdn.net/m0_61160520/article/details/136784799?spm=1001.2014.3001.5501
切点表达式icon-default.png?t=N7T8https://blog.csdn.net/m0_61160520/article/details/136782885?spm=1001.2014.3001.5501

案例 

1.创建项目

2.导入依赖

<dependency>                                       <groupId>mysql</groupId>                       <artifactId>mysql-connector-java</artifactId>  <version>8.0.25</version>                      
</dependency>                                      
<dependency>                                       <groupId>com.alibaba</groupId>                 <artifactId>druid</artifactId>                 <version>1.2.8</version>                       
</dependency>                                      
<!-- spring-jdbc -->                               
<dependency>                                       <groupId>org.springframework</groupId>         <artifactId>spring-jdbc</artifactId>           <version>6.0.6</version>                       
</dependency>                                      <dependency>                                       <groupId>org.springframework</groupId>         <artifactId>spring-tx</artifactId>             <version>6.0.6</version>                       
</dependency>                                      

3.数据库准备 

-- ----------------------------
-- Table structure for students
-- ----------------------------
DROP TABLE IF EXISTS `students`;
CREATE TABLE `students`  (`id` int NOT NULL,`name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,`gender` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,`age` int NULL DEFAULT NULL,`class` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of students
-- ----------------------------
INSERT INTO `students` VALUES (1, '喜羊羊', '男', 18, '高中一班');
INSERT INTO `students` VALUES (2, '美羊羊', '女', 19, '高中二班');
INSERT INTO `students` VALUES (3, '懒羊羊', '男', 18, '高中一班');
INSERT INTO `students` VALUES (4, '沸羊羊', '男', 18, '高中三班');
INSERT INTO `students` VALUES (5, '暖羊羊', '女', 19, '高中二班');
INSERT INTO `students` VALUES (6, '软绵绵', '男', 60, '高中一班');
INSERT INTO `students` VALUES (7, '灰太狼', '男', 30, '高中三班');
INSERT INTO `students` VALUES (8, '红太狼', '女', 30, '高中二班');SET FOREIGN_KEY_CHECKS = 1;

4.外部配置文件jdbc.properties

cx.url=jdbc:mysql://localhost:3306/studb
cx.driver=com.mysql.cj.jdbc.Driver
cx.username=root
cx.password=123456

5.编写配置类

@Configuration
@ComponentScan("com.example")
@PropertySource("classpath:jdbc.properties")
//@EnableAspectJAutoProxy //开启aspectj注解的支持
@EnableTransactionManagement //开启事务注解的支持
public class JavaConfig {/*从配置文件中读取数据库连接的相关信息。*/@Value("${cx.driver}")private String driver;@Value("${cx.url}")private String url;@Value("${cx.username}")private String username;@Value("${cx.password}")private String password;//druid连接池,使用 Druid 连接池来管理数据库连接。@Beanpublic DataSource dataSource(){DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(driver);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}//创建一个 JdbcTemplate bean,将上面创建的数据源对象注入其中,用于执行数据库查询和更新操作。@Beanpublic JdbcTemplate jdbcTemplate(DataSource dataSource){JdbcTemplate jdbcTemplate = new JdbcTemplate();jdbcTemplate.setDataSource(dataSource);return jdbcTemplate;}//创建一个用于管理事务的 TransactionManager bean,将数据源对象注入其中,以便在事务中控制数据库的操作。@Beanpublic TransactionManager transactionManager(DataSource dataSource){//内部要进行事务的操作,基于的连接池DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();//需要连接池对象dataSourceTransactionManager.setDataSource(dataSource);return dataSourceTransactionManager;}
}

6.简单准备一个dao/service层

dao

@Repository
public class StudentDao {//声明一个 JdbcTemplate 对象作为成员变量来执行数据库操作。private JdbcTemplate jdbcTemplate;@Autowiredpublic void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}public void updateNameById(String name, Integer id){String sql = "update students set name = ? where id = ? ;";int rows = jdbcTemplate.update(sql, name, id);}public void updateAgeById(Integer age,Integer id){String sql = "update students set age = ? where id = ? ;";jdbcTemplate.update(sql,age,id);}
}

service(重要内容)

添加事务:

 @Transactional
      位置: 方法 | 类上
      方法: 当前方法有事务
      类上: 类下的所有方法都有事务

 1.只读模式

         只读模式可以提升查询事务的效率! 推荐事务中只有查询代码,使用只读模式!
         默认: boolean readOnly() default false;
         解释: 一般情况下,都是通过类添加注解添加事务!
         类下的所有方法都有事务!
         查询方法可以通过再次添加注解,设置为只读模式,提高效率!

 2.超时时间

         默认: 永远不超时  -1
         设置 timeout = 时间 秒数  超过时间,就会回滚事务和释放异常!         TransactionTimedOutException
        如果类上设置事务属性,方法也设置了事务注解! 方法会不会生效??
        不会生效: 方法上的注解覆盖了类上的注解!

 3.指定异常回滚和指定异常不回滚:

        默认情况下,指定发生运行时异常事务才会回滚!
        我们可以指定Exception异常来控制所有异常都回滚!
        rollbackFor = Exception.class
        noRollbackFor = 回滚异常范围内,控制某个异常不回滚!

 4.隔离级别设置

        推荐设置第二个隔离级别!
        isolation = Isolation.READ_COMMITTED

@Transactional(timeout = 3)//超时时间
@Service
public class StudentService {private StudentDao studentDao;@Autowiredpublic void setStudentDao(StudentDao studentDao) {this.studentDao = studentDao;}@Transactional(readOnly = false ,rollbackFor = Exception.class , noRollbackFor = FileNotFoundException.class,isolation = Isolation.READ_COMMITTED)public void changeInfo() throws FileNotFoundException {studentDao.updateAgeById(99, 1);new FileInputStream("xxxx");studentDao.updateNameById("test3", 1);}@Transactional(readOnly = true)public void changeInfo2() {//查询 没有必要添加事务!//获取学生信息 查询数据库 不修改}/*** 声明两个独立修改数据库的事务业务方法* propagation = Propagation.REQUIRED 父方法有事务,我们就加入到父方法的事务!*              最终是同一个事务! 推荐使用默认值!!** propagation = Propagation.REQUIRES_NEW*               不管父方法是否有事务,我都是独立的事务!*               两个事务或者三个事务!*/@Transactional(propagation = Propagation.REQUIRED)public void changeAge(){studentDao.updateAgeById(8,1);}@Transactional(propagation = Propagation.REQUIRED)public void changeName(){studentDao.updateNameById("二狗子",1);int i = 1/0; //报错}
}

封装类TopService

@Service
public class TopService {@Autowiredprivate StudentService studentService;@Transactionalpublic void  topService(){studentService.changeAge();studentService.changeName();}
}

为什么要这个封装类呢?移步以下博客

主要涉及了事务的控制与管理 icon-default.png?t=N7T8https://blog.csdn.net/m0_61160520/article/details/136966627?spm=1001.2014.3001.5501

7.测试

@SpringJUnitConfig(JavaConfig.class)
public class TxTest {@Autowiredprivate TopService topService;@Autowiredprivate StudentService studentService;@Testpublic void  testTx() throws FileNotFoundException {topService.topService();}
}

结果:数据库中age被修改,因为使用的Propagation.REQUIRES_NEW,表示每个方法都会创建一个新的事务,独立于外部事务,即使其他方法报错,正常方法会被执行。

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

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

相关文章

Cache缓存:HTTP缓存策略解析

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

select , poll, epoll思维导图

目录 1. 总的框架结构 2. select 3. poll 4. epoll 1. 总的框架结构 2. select

SpringCloud-Gateway服务网关

一、网关介绍 1. 为什么需要网关 Gateway网关是我们服务的守门神&#xff0c;所有微服务的统一入口。 网关的核心功能特性&#xff1a; 请求路由 权限控制 限流 架构图&#xff1a; 权限控制&#xff1a;网关作为微服务入口&#xff0c;需要校验用户是是否有请求资格&am…

使用阿里云服务器搭建网站教程,超简单10分钟网站上线

使用阿里云服务器快速搭建网站教程&#xff0c;先为云服务器安装宝塔面板&#xff0c;然后在宝塔面板上新建站点&#xff0c;阿里云服务器网aliyunfuwuqi.com以搭建WordPress网站博客为例&#xff0c;来详细说下从阿里云服务器CPU内存配置选择、Web环境、域名解析到网站上线全流…

基于python+vue分类信息服务平台移动端的设计与实现flask-django-php-nodejs

分类信息服务平台是在Android操作系统下的应用平台。为防止出现兼容性及稳定性问题&#xff0c;框架选择的是django&#xff0c;Android与后台服务端之间的数据存储主要通过MySQL。用户在使用应用时产生的数据通过 python等语言传递给数据库。通过此方式促进分类信息服务平台信…

蓝桥杯单片机快速开发笔记——PCF8591的DAC模拟电压输出

一、原理分析 PCF8591电压信号探测器&#xff1a;http://t.csdnimg.cn/R38tC IIC原理&#xff1a;http://t.csdnimg.cn/v4dSv IIC指令&#xff1a;http://t.csdnimg.cn/RY6yi HC573/HC138&#xff1a;http://t.csdnimg.cn/W0a0U 数码管&#xff1a;http://t.csdnimg.cn/kfm9Y 独…

鸿蒙OpenHarmony开发实战:【MiniCanvas】

介绍 基于OpenHarmony的Cavas组件封装了一版极简操作的MiniCanvas&#xff0c;屏蔽了原有Canvas内部复杂的调用流程&#xff0c;支持一个API就可以实现相应的绘制能力&#xff0c;该库还在继续完善中&#xff0c;也欢迎PR。 使用说明 添加MiniCanvas依赖 在项目entry目录执行…

Docker学习笔记 - 常用命令

目录 基本概念常用命令使用docker compose启动脚本创建自己的image Docker命令文档 1. 下载一个image 从hub.docker.com下载一个image。 docker pull [image name]下载时指定image的tag。 docker pull [image name]:<tag>举例&#xff0c;下载postgre的tag为alpine…

CPP容器vector和list,priority_queue定义比较器

#include <iostream> #include <bits/stdc.h> using namespace std; struct VecCmp{bool operator()(int& a,int& b){return a>b;/*** 对于vector和list容器&#xff0c;这里写了&#xff1e;就是从大到小* 对于priority_queue容器&#xff0c;这里写…

配置java8和java11以及输入version命令没反应问题

电脑重置重新安装java8和java11记录一下供自己观看 安装过程掠过我自己能看懂就行 需要记录一下 因为JDK11以后Oracle把JRE集成到了JDK中&#xff0c;在安装JDK11及更高版本的JDK时&#xff0c;默认是不会自动安装JRE的。在jdk11的安装目录下打开命令行窗口或者shift鼠标右键…

婚恋小程序开发的资质需要哪些?维护成本高吗?

随着互联网的高速发展&#xff0c;人们的生活方式也在发生着翻天覆地的变化。在这个变化中&#xff0c;婚恋市场也逐渐走向了线上&#xff0c;婚恋小程序应运而生。那么&#xff0c;开发一款婚恋小程序需要哪些资质呢&#xff1f;维护成本又高不高呢&#xff1f;本文将从这两个…

2024年新算法!PCA+CPO+K-means聚类,冠豪猪优化器(CPO)优化K-means,适合学习,也适合发paper

2024年新算法&#xff01;PCACPOK-means聚类&#xff0c;冠豪猪优化器&#xff08;CPO)优化K-means&#xff0c;适合学习&#xff0c;也适合发paper。 一、冠豪猪优化器 摘要&#xff1a;受冠豪猪(crest Porcupine, CP)的各种防御行为启发&#xff0c;提出了一种新的基于自然…

【C语言】结构体与位段

一、前言 我们之前学习过定义一个整型类型的变量又或者定义一个浮点型类型的变量...&#xff0c;这些变量可以描述一个整数又或者描述一个小数...&#xff0c;可无论是整数还是小数...&#xff0c;它们也只是简单对象。如果我们想要描述像一本书&#xff0c;一个人这种复杂对象…

【算法与数据结构】深入二叉树实现超详解

文章目录 &#x1f4dd;前言&#x1f320; 接口函数✏️ 实现函数&#x1f309;创建树的新节点&#x1f320;通过前序遍历的数组构建二叉树&#x1f309;包装通过前序遍历的数组构建二叉树&#x1f320;二叉树的销毁&#x1f320;层次遍历&#x1f320;第一种实现&#xff1a;不…

Android: Gradle 命令

一、查看整个项目依赖传递关系 x.x.x (*) 该依赖已经有了&#xff0c;将不再重复依赖。x.x.x -> x.x.x 该依赖的版本被箭头所指的版本代替。x.x.x -> x.x.x(*) 该依赖的版本被箭头所指的版本代替&#xff0c;并且该依赖已经有了&#xff0c;不再重复依赖。 1. gradlew ap…

002 高并发内存池_定长内存池设计

​&#x1f308;个人主页&#xff1a;Fan_558 &#x1f525; 系列专栏&#xff1a;高并发内存池 &#x1f339;关注我&#x1f4aa;&#x1f3fb;带你学更多知识 文章目录 前言一、设计整体框架二、New操作&#xff08;申请空间&#xff09;三、Delete操作&#xff08;用自由链…

奇舞周刊第523期:来自 rust 生态的强烈冲击?谈谈 Leptos 在语法设计上的精妙之处...

奇舞推荐 ■ ■ ■ 来自 rust 生态的强烈冲击&#xff1f;谈谈 Leptos 在语法设计上的精妙之处 过去很长一段时间&#xff0c;前端框架们都在往响应式的方向发展。同时又由于 React hooks 的深远影响&#xff0c;函数式 响应式成为了不少前端心中最理想的前端框架模样。Solid …

设计模式-初步认识

目录 &#x1f6fb;1.什么是设计模式 &#x1f69a;2.设计模式的优点 &#x1f68d;3.设计模式6大原则 &#x1f6f4;4.设计模式类型 1.什么是设计模式 设计模式代表了最佳的实践&#xff0c;通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开…

Yocto学习笔记1-下载与首次编译

Yocto学习笔记1-下载与首次编译 1、基础环境介绍2、注意点3、安装依赖3.1 yocto常规系统构建所需依赖库&#xff08;较全&#xff09;3.2 龙芯适配时的最小依赖库&#xff08;最小&#xff09; 4、下载4.1 通过git克隆4.2 查看所有远程分支4.3 签出一个长期支持的稳定版本4.4 查…

从边缘设备丰富你的 Elasticsearch 文档

作者&#xff1a;David Pilato 我们在之前的文章中已经了解了如何丰富 Elasticsearch 本身和 Logstash 中的数据。 但如果我们可以从边缘设备中做到这一点呢&#xff1f; 这将减少 Elasticsearch 要做的工作。 让我们看看如何从具有代理处理器的 Elastic 代理中执行此操作。 E…