当前位置: 首页 > article >正文

spring--声明式事务

声明式事务

1、回顾事务

  • 要么都成功,要么都失败!

  • 事务在项目开发中,十分重要,涉及数据的一致性问题

  • 确保完整性和一致性

事务ACID:

  • 原子性:事务是原子性操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么完全不起作用

  • 一致性:

    • 一旦所有事务动作完成,事务就要被提交。数据和资源处于一种满足业务规则的一致性状态中

  • 隔离性

    • 多个业务可能操作同一个资源,防止数据损坏

  • 持久性

    • 事务一旦提交,无论系统发生什么问题,结果都不会被影响,被持久性地写进存储器中

    测试

    将上面的代码拷贝到一个新项目中

    在之前的案例中,我们给userDao接口新增两个方法,删除和增加用户;

     //添加一个用户int addUser(User user);​//根据id删除用户int deleteUser(int id);

    mapper文件,我们故意把 deletes 写错,测试!

     <insert id="addUser" parameterType="com.kuang.pojo.User">insert into user (id,name,pwd) values (#{id},#{name},#{pwd})</insert>​<delete id="deleteUser" parameterType="int">deletes from user where id = #{id}</delete>

    编写接口的实现类,在实现类中,我们去操作一波

     public class UserDaoImpl extends SqlSessionDaoSupport implements UserMapper {​//增加一些操作public List<User> selectUser() {User user = new User(4,"小明","123456");UserMapper mapper = getSqlSession().getMapper(UserMapper.class);mapper.addUser(user);mapper.deleteUser(4);return mapper.selectUser();}​//新增public int addUser(User user) {UserMapper mapper = getSqlSession().getMapper(UserMapper.class);return mapper.addUser(user);}//删除public int deleteUser(int id) {UserMapper mapper = getSqlSession().getMapper(UserMapper.class);return mapper.deleteUser(id);}​}

    测试

     @Testpublic void test2(){ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");UserMapper mapper = (UserMapper) context.getBean("userDao");List<User> user = mapper.selectUser();System.out.println(user);}

    报错:sql异常,delete写错了

    结果 :插入成功!

    没有进行事务的管理;我们想让他们都成功才成功,有一个失败,就都失败,我们就应该需要事务!

    以前我们都需要自己手动管理事务,十分麻烦!

    但是Spring给我们提供了事务管理,我们只需要配置即可;

spring中的事务管理

Spring在不同的事务管理API之上定义了一个抽象层,使得开发人员不必了解底层的事务管理API就可以使用Spring的事务管理机制。Spring支持编程式事务管理和声明式的事务管理

  • 声明式事务:

    • 一般情况下比编程式事务好用。

    • 将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。

    • 将事务管理作为横切关注点,通过aop方法模块化。Spring中通过Spring AOP框架支持声明式事务管理。

  • 编程式事务:

    • 将事务管理代码嵌到业务方法中来控制事务的提交和回滚

    • 缺点:必须在每个事务操作业务逻辑中包含额外的事务管理代码

使用Spring管理事务,注意头文件的约束导入 : tx

 xmlns:tx="http://www.springframework.org/schema/tx"​http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd">

事务管理器

  • 无论使用Spring的哪种事务管理策略(编程式或者声明式)事务管理器都是必须的。

  • 就是 Spring的核心事务管理抽象,管理封装了一组独立于技术的方法。

JDBC事务

 <bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean>

配置好事务管理器后我们需要去配置事务的通知

 <!--配置事务通知--><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!--配置哪些方法使用什么样的事务,配置事务的传播特性--><tx:method name="add" propagation="REQUIRED"/><tx:method name="delete" propagation="REQUIRED"/><tx:method name="update" propagation="REQUIRED"/><tx:method name="search*" propagation="REQUIRED"/><tx:method name="get" read-only="true"/><tx:method name="*" propagation="REQUIRED"/></tx:attributes></tx:advice>

spring事务传播特性:

事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。spring支持7种事务传播行为:

  • propagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择。

  • propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。

  • propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。

  • propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。

  • propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

  • propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。

  • propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作

Spring 默认的事务传播行为是 PROPAGATION_REQUIRED,它适合于绝大多数的情况。

假设 ServiveX#methodX() 都工作在事务环境下(即都被 Spring 事务增强了),假设程序中存在如下的调用链:Service1#method1()->Service2#method2()->Service3#method3(),那么这 3 个服务类的 3 个方法通过 Spring 的事务传播机制都工作在同一个事务中。

就好比,我们刚才的几个方法存在调用,所以会被放在一组事务当中!

配置AOP

导入aop的头文件!

 <!--配置aop织入事务--><aop:config><aop:pointcut id="txPointcut" expression="execution(* com.kuang.dao.*.*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/></aop:config>

进行测试

删掉刚才插入的数据,再次测试!

 @Testpublic void test2(){ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");UserMapper mapper = (UserMapper) context.getBean("userDao");List<User> user = mapper.selectUser();System.out.println(user);}

思考问题?

为什么需要配置事务?

  • 如果不配置,就需要我们手动提交控制事务;

  • 事务在项目开发过程非常重要,涉及到数据的一致性的问题,不容马虎!

相关文章:

spring--声明式事务

声明式事务 1、回顾事务 要么都成功&#xff0c;要么都失败&#xff01; 事务在项目开发中&#xff0c;十分重要&#xff0c;涉及数据的一致性问题 确保完整性和一致性 事务ACID&#xff1a; 原子性&#xff1a;事务是原子性操作&#xff0c;由一系列动作组成&#xff0c;…...

小甲鱼第004讲:变量和字符串(下)| 课后测试题及答案

问答题: 0. 请问下面代码有没有毛病&#xff0c;为什么? 请问下面代码为什么会出错&#xff0c;应该如何解决&#xff1f; 答:这是由于在字符串中&#xff0c;反斜杠()会与其随后的字符共同构成转义字符。 为了避免这种不测情况的发生&#xff0c;我们可以在字符串的引号前面…...

MergeX亮相GTC2025:开启全球广告流量交易新篇章

全球流量盛宴GTC2025深圳启幕&#xff0c;共探出海新蓝海 2025年4月24日至25日&#xff0c;GTC2025全球流量大会将在深圳福田会展中心9号馆隆重召开。作为跨境出海领域内规模最大、资源最丰富、产业链最完备的年度盛会&#xff0c;此次大会将汇聚众多行业精英&#xff0c;共同探…...

Python(10.2)Python可变与不可变类型内存机制解密:从底层原理到工程实践

目录 一、类型特性引发的内存现象1.1 电商促销活动事故分析1.2 内存机制核心差异 二、内存地址追踪实验2.1 基础类型验证2.2 复合对象实验 三、深度拷贝内存分析3.1 浅拷贝陷阱3.2 深拷贝实现 四、函数参数传递机制4.1 默认参数陷阱4.2 安全参数模式 五、内存优化最佳实践5.1 字…...

STM32(基于标准库)

参考博客&#xff1a;江科大STM32笔记 Stm32外设 一、GPIO 基础 GPIO位结构 I/O引脚的保护二极管是对输入电压进行限幅的上面的二极管接VDD, 3.3V,下面接VSS, 0V&#xff0c;当输入电压 >3.3V 那上方这个二极管就会导通&#xff0c;输入电压产生的电流就会大部分充入VD…...

国家优青ppt美化_青年科学基金项目B类ppt案例模板

国家优青 国家优青&#xff0c;全称“国家优秀青年基金获得者”。2025改名青年科学基金B类。 作为自然基金人才资助类型&#xff0c;支持青年学者在基础研究方面自主选择研究方向开展创新研究。它是通往更高层次科研荣誉的重要阶梯&#xff0c;是准杰青梯队。 / WordinPPT /…...

解决 ECharts 图表无数据显示问题

问题&#xff1a; 在开发项目时&#xff0c;后端明明已经成功返回了数据&#xff0c;但在展示手账发布数量趋势和树洞帖子发布数量趋势的 ECharts 图表中&#xff0c;却只有坐标轴&#xff0c;没有任何数据显示。 以我的VUE项目开发可视化面板为例&#xff0c;下面将详细分析可…...

spacy安装失败报错

报错 使用命令pip install spacy安装spacy时总是报错&#xff08;python -m pip install spacy方式安装同样报错&#xff09; 解决办法 使用conda安装&#xff0c;conda能够避免很多不必要的依赖包。 命令&#xff1a;conda install spacy 安装成功列表展示...

C++在Linux上生成动态库并调用接口测试

加减乘除demo代码 项目结构 CPP/ ├── calculator.cpp ├── calculator.h ├── main.cpp 头文件 #ifndef CALCULATOR_H #define CALCULATOR_H#ifdef __cplusplus extern "C" {#endifdouble add(double a, double b);double subtract(double a, double b…...

第三篇:Python数据结构深度解析与工程实践

第一章:列表与字典 1.1 列表的工程级应用 1.1.1 动态数组实现机制 Python列表底层采用动态数组结构,初始分配8个元素空间,当空间不足时按0,4,8,16,25,35...的公式扩容,每次扩容增加约12.5%的容量 通过sys模块可验证扩容过程: import sys lst = [] prev_size = 0 for …...

前端性能测试工具 —— WebPageTest

测试工具介绍 WebPageTest 是一个用于测量和分析网页性能的工具。它提供了详细的诊断信息&#xff0c;帮助用户了解网页在不同条件下的表现。用户可以选择全球不同的测试地点&#xff0c;使用真实的浏览器&#xff0c;并自定义网络条件进行测试。WebPageTest 还支持核心网络指…...

北邮LLMs在导航中的应用与挑战!大模型在具身导航中的应用进展综述

作者&#xff1a;Jinzhou Lin, Han Gao, Xuxiang Feng, Rongtao Xu, Changwei Wang, Man Zhang, Li Guo, Shibiao Xu 单位&#xff1a;北京邮电大学人工智能学院&#xff0c;中国科学院自动化研究所多模态人工智能系统国家重点实验室&#xff0c;中科院空间信息研究所&#xf…...

Windows下ElasticSearch8.x的安装步骤

下载ElasticSearch&#xff1a;https://www.elastic.co/downloads/elasticsearch &#xff08;我下载的是目前最新版8.17.4&#xff09;解压ElasticSearch 进入到ElasticSearch的bin目录下双击elasticsearch.bat 弹出控制台并开始执行&#xff0c;在这一步会输出初始账号和密码…...

【高性能缓存Redis_中间件】一、快速上手redis缓存中间件

一、铺垫 在当今的软件开发领域&#xff0c;消息队列扮演着至关重要的角色。它能够帮助我们实现系统的异步处理、流量削峰以及系统解耦等功能&#xff0c;从而提升系统的性能和可维护性。Redis 作为一款高性能的键值对数据库&#xff0c;不仅提供了丰富的数据结构&#xff0c;…...

AI Agent入门指南

图片来源网络 ‌一、开箱暴击&#xff1a;你以为的"智障音箱"&#xff0c;其实是赛博世界的007‌ ‌1.1 从人工智障到智能叛逃&#xff1a;Agent进化史堪比《甄嬛传》‌ ‌青铜时代&#xff08;2006-2015&#xff09;‌ “小娜同学&#xff0c;关灯” “抱歉&…...

React 第三十节 使用 useState 和 useEffect Hook实现购物车

不使用 redux 实现 购物车案例 使用 React 自带的 useState 和 useEffect Hook 即可实现购物车 export default function ShoppingCar() {// 要结算的商品 总数 以及总价const [totalNum, setTotalNum] useState(0)const [totalPerice, setTotalPerice] useState(0)// 商品…...

Git的简介和简单的命令使用介绍

Git 是一种分布式版本控制系统&#xff0c;常用于跟踪文件的变化&#xff0c;协作开发和管理代码版本。以下是 Git 的基本概念和使用方式&#xff1a; 仓库&#xff08;Repository&#xff09;&#xff1a;Git 仓库是用来存储项目文件和版本历史的地方。可以通过在本地或远程创…...

概念辨析:Redis 多路 I/O 复用和多线程

Redis 多路 I/O 复用是在 Redis 2.0 引入的&#xff0c;而 Redis 多线程是在 Redis 6.0 引入的&#xff0c;两者不是同一个概念。 多路复用的本质还是同步 I/O&#xff0c;因为最终都需要主线程调用 read() 方法把数据拷贝到用户态。 在并发量非常大的情况下&#xff0c;Redi…...

海洋大地测量基准与水下导航系列之八我国海洋水下定位装备发展现状

中国国家综合PNT体系建设重点可概括为“51N”&#xff0c;“5”指5大基础设施&#xff0c;包括重点推进下一代北斗卫星导航系统、积极发展低轨导航增强系统、按需发展水下导航系统、大力发展惯性导航系统、积极探索脉冲星导航系统&#xff1b;“1”是实现1个融合发展&#xff0…...

计算机系统设计中的一些常用方法

面试中经常被问到&#xff1a; 有一个亿qq号&#xff0c;找出重复的 给你512m内存&#xff0c;找出5g文件中最大的数字 订单超时实现精准关单 … 当然&#xff0c;还有经常遇到的问题&#xff1a; 接口业务逻辑复杂或查数据库慢&#xff0c;相应耗时高 网络因为丢包导致服…...

【征程 6】工具链 VP 示例中 Cmakelists 解读

1. 引言 在文章【征程 6】VP 简介与单算子实操中&#xff0c;介绍了 VP 是什么&#xff0c;并以单算子 rotate 为例&#xff0c;介绍了 VP API 使用方法。在【征程 6】工具链 VP 示例中日志打印解读 中介绍了 VP 单算子示例中用到的日志打印的头文件应该怎么写。接下来和大家一…...

深入解析 Jenkins Agent 的 .jnlp 启动文件

&#x1f9e9; 深入解析 Jenkins Agent 的 .jnlp 启动文件 在 Jenkins 中&#xff0c;通过 JNLP&#xff08;Java Network Launch Protocol&#xff09;方式连接 Agent 是一种常见且灵活的方式。你可能曾见过类似这样的命令&#xff1a; java -jar agent.jar -jnlpUrl file:/…...

谷歌开源代理开发工具包(Agent Development Kit,ADK):让多智能体应用的构建变得更简

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

0x01、Redis 主从复制的实现原理是什么?

Redis 主从复制概述 Redis 的主从复制是一种机制&#xff0c;允许一个主节点&#xff08;主实例&#xff09;将数据复制到一个或多个从节点&#xff08;从实例&#xff09;。通过这一机制&#xff0c;从节点可以获取主节点的数据并与之保持同步。 复制流程 开始同步&#xf…...

noscript 标签是干什么的

vue public目录下的 index.html 会有 <noscript> 标签不知道是干吗的。 其实 noscript 标签在不支持或是禁用JavaScript 的浏览器中显示替代的内容。这个元素可以包含任何 HTML 元素。这个标签的用法也非常简单&#xff1a; <noscript><strong>Were sorry …...

[创业之路-366]:投资尽职调查 - 尽调核心逻辑与核心影响因素:价值、估值、退出、风险、策略

目录 一、VC投资的本质是冒着不确定性风险进行买卖、生意&#xff0c;为了赚取高额回报 1、VC投资的核心本质 2、VC投资的运作机制 3、VC投资的风险与挑战 4、VC投资的底层逻辑 5、总结&#xff1a;VC投资的本质再定义 二、尽调核心逻辑 1、尽调的含义 2、尽调的逻辑方…...

MOP数据库中的EXPLAIN用法

EXPLAIN 是 SQL 中的一个非常有用的工具&#xff0c;主要用于分析查询语句的执行计划。执行计划能展示数据库在执行查询时的具体操作步骤&#xff0c;像表的读取顺序、使用的索引情况、数据的访问方式等&#xff0c;这有助于我们对查询性能进行优化。 语法 不同的数据库系统&…...

Hyprnote开源程序是一款记录和转录您会议的 AI 记事本。 本地优先且可扩展 。

一、软件介绍 文末提供源码下载学习 Hyprnote开源程序是一款记录和转录您会议的 AI 记事本。 从您的原始会议记录中生成强大的摘要&#xff0c;本地优先且可扩展 。使用开源模型 &#xff08;Whisper & Llama&#xff09; 离线工作&#xff0c;高度可扩展 &#xff0c;由插…...

MSCKF及可观性总结

可观性 参考链接 真实VIO系统不能观的维度是4&#xff08;位置和yaw角&#xff09;&#xff0c;由于EKF的转移和观测Jacobian矩阵的线性化点不同、不可观方向噪声的存在&#xff0c;实际MSCKF不能观的维度变成了3&#xff0c;绕重力轴的旋转&#xff08;yaw角&#xff09;被错…...

上篇:新能源轻卡城配物流经济/动力模式量化定义(理论篇)——数学暴力破解工程困局

副标题&#xff1a;用微分方程撕开模式切换本质&#xff0c;用传感器数据重构载重真相 引言&#xff1a;为什么轻卡模式定义比乘用车难10倍&#xff1f; 行业现状痛点&#xff1a; 中国新能源轻卡日均载重波动高达300%&#xff08;空载0kg→满载4.5吨&#xff09;某头部车企实…...