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.rhkb.cn/news/283710.html

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

相关文章

3、Jenkins持续集成-Jenkins安装和插件管理

文章目录 一、Jenkins安装1. 安装JDK2. 获取jenkins安装包3. 安装包上传到服务器&#xff0c;进行安装4. 修改Jenkins配置&#xff08;1&#xff09;低版本Jenkins的rpm包&#xff08;2&#xff09;高版本Jenkins的rpm包 5. 启动Jenkins6. 打开浏览器访问7. 获取并输入admin账户…

公司内部局域网怎么适用飞书?

随着数字化办公的普及&#xff0c;企业对于内部沟通和文件传输的需求日益增长。飞书作为一款集成了即时通讯、云文档、日程管理、视频会议等多种功能的智能协作平台&#xff0c;已经成为许多企业提高工作效率的首选工具。本文将详细介绍如何在公司内部局域网中应用飞书&#xf…

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…

拷贝他人maven仓库jar包到自己本地仓库,加载maven依然提示无法下载对应依赖

所遇问题&#xff1a; 拷贝他人maven仓库jar包到自己本地maven仓库repository下的对应依赖位置&#xff0c;重新加载idea的maven依然提示无法下载对应依赖。 解决办法&#xff1a; 在maven->repository找到对应报错依赖路径&#xff0c;删除xxx.repositories 和 xxx.lastU…

如何使用 ArcGIS Pro 制作好看的高程渲染图

虽然 ArcGIS Pro 已经提供了很多好看的配色方案&#xff0c;但是如果直接对高程DEM进行渲染效果不是很理想&#xff0c;我们可以结合山体阴影让高程渲染图看起来更加立体&#xff0c;这里为大家介绍一下制作方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是…

【Python使用】python高级进阶知识md总结第5篇:获取进程编号,1. 获取进程编号的目的【附代码文档】

python高级进阶全知识知识笔记总结完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;操作系统&#xff0c;虚拟机软件&#xff0c;Ubuntu操作系统&#xff0c;Linux内核及发行版&#xff0c;查看目录命令&#xff0c;切换目录命令&#xff0c;绝对路径和相对…

EPO企业生产运营数智化平台助力制造企业迈向智能制造

随着“中国制造2025”和工业4.0的不断推进&#xff0c;越来越多的制造企业准备迈入智能制造和智慧制造领域&#xff0c;实现数智化管理。企业通过搭建EPO企业生产运营平台&#xff0c;结合自身业务现状和数字化需求&#xff0c;从各个业务场景、部门人员、产品组成等方面进行分…

通过nginx配置文件服务器(浏览器访问下载)

配置服务器端文件下载和展示(Nginx) nginx.conf文件中增加配置&#xff0c;然后浏览器里访问ip:port回车即可 server { listen port; server_name 服务端ip; # 指定文件下载目录的路径 location / { # 使用root指令来设置文件的根目录 # Nginx会在该目录下寻找相对于loca…

Docker-Container

Docker ①什么是容器②为什么需要容器③容器的生命周期容器 OOM容器异常退出容器暂停 ④容器命令清单总览docker createdocker rundocker psdocker logsdocker attachdocker execdocker startdocker stopdocker restartdocker killdocker topdocker statsdocker container insp…

第四百二十回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"自定义标题栏"相关的内容&#xff0c;本章回中将介绍自定义Action菜单.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在这里提到的…

Excel使用VLOOKUP函数

VLOOKUP(lookup_value,table_array,col_index_num,range_lookup) 释义&#xff1a; lookup_value&#xff1a;要查找的值&#xff0c;包括数字&#xff0c;文本等 table_array&#xff1a;要查找的值以及预期返回的内容所在的区域 col_index_num&#xff1a;查找的区域的列…

第 6 章 ROS-xacro练习(自学二刷笔记)

重要参考&#xff1a; 课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ 讲义链接:Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 6.4.3 Xacro_完整使用流程示例 需求描述: 使用 Xacro 优化 URDF 版的小车底盘模型实现 结果演示: 1.编写 X…

《优化接口设计的思路》系列:第九篇—用好缓存,让你的接口速度飞起来

一、前言 大家好&#xff01;我是sum墨&#xff0c;一个一线的底层码农&#xff0c;平时喜欢研究和思考一些技术相关的问题并整理成文&#xff0c;限于本人水平&#xff0c;如果文章和代码有表述不当之处&#xff0c;还请不吝赐教。 作为一名从业已达六年的老码农&#xff0c…

如何用联合(共用体)union验证系统大小端

一&#xff1a;思路 由联合体的特点&#xff0c;可知上图&#xff0c;char c 和 int i 共用四个字节&#xff0c;假设是小端&#xff0c;则由左到右是低地址到高地址&#xff0c;四个字节的内容如图所示01 00 00 00 代码展示&#xff1a; 如果第一个字节是1&#xff0c;则证明…

体育竞赛成绩管理系统设计与实现|jsp+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;…

南京大学AI考研,宣布改考408!

官网还没通知 附上南大与同层次学校近四年的分数线对比&#xff0c;整体很难 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 如果确定要冲南大的话建议提早调整自己的复习路线&…

sqlite3 交叉编译

#1.下载源码并解压 源码路径如下&#xff0c;下载autoconf版本 SQLite Download Page 解压 tar -zxvf sqlite-autoconf-3450200.tar.gz cd sqlite-autoconf-3450200 mkdir build # 2. 配置源代码 # 假设你已经安装了交叉编译工具链&#xff0c;如gcc-arm-linux-gnueabih…

Python爬取歌曲宝音乐:轻松下载Jay的歌

歌曲宝是一个不用付费就能听jay的歌曲&#xff0c;但是每次都只能播放一首不方便&#xff0c;于是今天想把它下载下来&#xff0c;本地循环播放&#xff0c;它所用到的接口是某我的还不错哈 获取搜索接口 分析html请求接口&#xff0c;获取到的数据是直接渲染好的HTML内容&…

Python-VBA编程500例-016(入门级)

移动石子算法(Stone-moving Algorithm)是一类在计算机科学和数学中广泛研究的算法问题&#xff0c;通常涉及在特定规则下移动石子以达到某种目标。虽然这些问题本身可能看起来是抽象的&#xff0c;但它们在实际应用中有多种体现&#xff0c;包括但不限于以下领域&#xff1a; …

stable diffusion 提示词进阶语法-年龄身材肤色-学习小结

stable diffusion 提示词进阶语法-年龄&身材&肤色 前言年龄提示词青年&#xff08;18-25岁&#xff09;幼年、少年&#xff08;1-18&#xff09;中年&#xff08;35-60岁&#xff09;老年&#xff08;65-80岁 老爷爷 老奶奶&#xff09; 身材提示词肤色关键词(人物基础…