spring事务管理快速入门(以转账为例)
spring事务管理(以转账为例)
概述
Spring事务管理提供了一种在应用程序中管理事务的机制,它抽象了底层的事务管理细节,使得开发者可以更加专注于业务逻辑的实现,而不必过多关心事务的处理。以下是Spring事务管理的一般概述:
-
事务的概念: 事务是一组操作,它们被看作一个不可分割的工作单元,要么全部执行成功,要么全部不执行。在数据库中,事务通常用于确保数据库的一致性和完整性。
-
Spring事务抽象: Spring提供了一个强大的事务管理抽象,它包括两个核心概念:事务管理器(TransactionManager) 和 事务定义(TransactionDefinition)。
-
事务管理器(TransactionManager): 是一个接口,它负责事务的启动、提交和回滚。Spring有多个实现类,可以适用于不同的事务管理场景。
-
事务定义(TransactionDefinition): 定义了事务的属性,如隔离级别、传播行为、超时等。Spring允许通过XML或注解的方式来配置事务的属性。
-
-
声明式事务管理: Spring支持声明式事务管理,这意味着你可以通过配置文件或注解的方式来声明事务,而不必在代码中显式编写事务管理的逻辑。
-
XML配置方式: 通过XML配置文件中的
和
元素来声明事务。 -
注解配置方式: 使用
@Transactional
注解来标注需要事务管理的方法,然后通过配置启用注解驱动事务管理。
-
-
编程式事务管理: 除了声明式事务管理外,Spring还支持编程式事务管理,这意味着你可以在代码中显式控制事务的开始、提交和回滚。
-
使用
TransactionTemplate
类: Spring提供了TransactionTemplate
类,它封装了事务的基本操作,你可以在代码中使用它来编程式地管理事务。
-
-
事务传播行为: 在Spring中,事务的传播行为(Transaction Propagation Behavior)定义了在一个事务方法被另一个事务方法调用时,应该如何处理事务。Spring定义了七种事务传播行为:
-
PROPAGATION_REQUIRED(默认):
-
如果当前存在事务,则加入该事务;如果不存在事务,则创建一个新的事务。这是最常见的传播行为。
-
-
PROPAGATION_SUPPORTS:
-
如果当前存在事务,则加入该事务;如果不存在事务,则以非事务的方式执行。
-
-
PROPAGATION_MANDATORY:
-
如果当前存在事务,则加入该事务;如果不存在事务,则抛出异常。要求外部调用方必须在事务中调用。
-
-
PROPAGATION_REQUIRES_NEW:
-
无论当前是否存在事务,都创建一个新的事务。如果有事务存在,将它挂起。
-
-
PROPAGATION_NOT_SUPPORTED:
-
以非事务的方式执行操作,如果当前存在事务,则将其挂起。
-
-
PROPAGATION_NEVER:
-
以非事务方式执行操作,如果当前存在事务,则抛出异常。
-
-
PROPAGATION_NESTED:
-
如果当前存在事务,则创建一个嵌套事务,并且它是当前事务的一个保存点(savepoint)。如果不存在事务,则行为类似于
PROPAGATION_REQUIRED
。
-
-
-
事务隔离级别: 事务隔离级别定义了在多个事务同时执行时,一个事务对数据的修改对其他事务的可见性程度。Spring定义了五个事务隔离级别,每个级别都有不同的特性和影响:
-
READ_UNCOMMITTED(读取未提交):
-
特性:允许一个事务读取另一个事务未提交的数据。
-
可能问题:脏读、不可重复读、幻读。
-
-
READ_COMMITTED(读取已提交):
-
特性:一个事务只能读取已经提交的另一个事务的数据。
-
可能问题:不可重复读、幻读。
-
-
REPEATABLE_READ(可重复读):
-
特性:确保事务可以多次从相同的数据集读取相同的数据,即使其他事务正在修改这些数据。
-
可能问题:幻读。
-
-
SERIALIZABLE(序列化):
-
特性:事务是串行执行的,所有的事务都按顺序依次执行,不允许并发执行。
-
可能问题:性能较低,但避免了脏读、不可重复读、幻读。
-
-
DEFAULT:
-
使用数据库默认的隔离级别,通常是数据库的默认配置。
-
-
-
事务回滚规则: Spring允许你配置哪些异常触发事务回滚,哪些异常不触发事务回滚。
-
分布式事务: Spring提供对分布式事务的支持,通过
JtaTransactionManager
实现了对JTA事务的集成。
PlatformTransactionManager概述
Spring的事务管理模块定义了一个平台事务管理器(PlatformTransactionManager)接口,该接口有多种实现,以适应不同的事务管理机制。主要的实现类包括:
-
DataSourceTransactionManager: 用于基于JDBC的事务管理,适用于关系型数据库,如MySQL、PostgreSQL等。
-
HibernateTransactionManager: 用于基于Hibernate的事务管理,适用于使用Hibernate框架的应用。
-
JtaTransactionManager: 用于基于Java EE的JTA(Java Transaction API)事务管理,适用于复杂的分布式事务场景。
-
JpaTransactionManager: 用于基于JPA(Java Persistence API)的事务管理,适用于使用JPA的应用。
-
WebLogicJtaTransactionManager: 专门用于WebLogic服务器上的JTA事务管理。
实体类domain层
package domain; public class account {private String name;private int gold; public account(String name, int gold) {this.name = name;this.gold = gold;} public account() {} public String getName() {return name;} public void setName(String name) {this.name = name;} public int getGold() {return gold;} public void setGold(int gold) {this.gold = gold;} @Overridepublic String toString() {return "account{" +"name='" + name + '\'' +", gold=" + gold +'}';} }
Dao层
接口
package dao; public interface accountDao {public void out(String man,int money);转出public void in(String man,int money);转入 }
实现类
package dao.Impl; import dao.accountDao; import org.springframework.jdbc.core.JdbcTemplate; public class accountImpl implements accountDao {JdbcTemplate jdbcTemplate ; • public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { • this.jdbcTemplate = jdbcTemplate; • } • @Override • public void out(String man, int money) { • jdbcTemplate.update("update account set gold=gold-? where name=?",money,man); • } • @Override • public void in(String man,int money) { • jdbcTemplate.update("update account set gold=gold+? where name=?",money,man); • } }
service层
接口
package dao; public interface accountDao {public void out(String man,int money);public void in(String man,int money); }
实现类
package service.Impl; import dao.accountDao; import service.accountService; public class accountServiceImpl implements accountService { accountDao accountdao; public void setAccountdao(accountDao accountdao) {this.accountdao = accountdao;} @Overridepublic void transfer(String outman, String inman, int money) {accountdao.out(outman,money);int i=1/0;accountdao.in(inman,money);} }
ApplicationContext.xml配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><context:property-placeholder location="classpath:mysql.properties"></context:property-placeholder>配置数据源<bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${jdbc.Driver}"></property><property name="jdbcUrl" value="${jdbc.url}"></property><property name="user" value="${jdbc.user}"></property><property name="password" value="${jdbc.password}"></property></bean>配置jdbc模板<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="datasource"></property></bean><bean id="account" class="dao.Impl.accountImpl"><property name="jdbcTemplate" ref="jdbcTemplate"></property></bean><bean id="accountService" class="service.Impl.accountServiceImpl"><property name="accountdao" ref="account"></property></bean> <!-- 配置事务管理平台--> 这里是基于springjdbc模板实现的所以用的是DataSource<bean id="transaction"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="datasource"></property></bean> <!-- 通知--><tx:advice id="myAdvice" transaction-manager="transaction"><tx:attributes> <!-- 哪些方法被增强--><tx:method name="transfer"isolation="READ_COMMITTED"propagation="REQUIRED" read-only="false" 因为转账肯定需要修改 所以不是只读/></tx:attributes></tx:advice> <!-- 配置事务的aop织入--><aop:config><aop:advisor advice-ref="myAdvice"pointcut="execution(* service.Impl.accountServiceImpl.*(..))"/></aop:config> </beans>
注解式声明式事务管理
xml配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><context:property-placeholder location="classpath:mysql.properties"></context:property-placeholder>配置数据源<bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${jdbc.Driver}"></property><property name="jdbcUrl" value="${jdbc.url}"></property><property name="user" value="${jdbc.user}"></property><property name="password" value="${jdbc.password}"></property></bean>配置jdbc模板<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="datasource"></property></bean><bean id="account" class="dao.Impl.accountImpl"><property name="jdbcTemplate" ref="jdbcTemplate"></property></bean><bean id="accountService" class="service.Impl.accountServiceImpl"><property name="accountdao" ref="account"></property></bean> <!-- 配置事务管理平台--> 这里是基于springjdbc模板实现的所以用的是DataSource<bean id="transaction"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="datasource"></property></bean>新加<tx:annotation-driven transaction-manager="transaction"></tx:annotation-driven><context:component-scan base-package="org.dao.Impl" /><context:component-scan base-package="org.service.Impl" />组件扫描<aop:aspectj-autoproxy></aop:aspectj-autoproxy> 启用 AspectJ 自动代理<context:annotation-config></context:annotation-config>启用注解驱动的配置,包括支持注解驱动的 AOP。在这个上下文中,主要是为了支持 @Transactional 注解,它用于启用声明式事务管理。在这个配置中,它会启用对带有 @Repository, @Service, @Controller 和其他注解的类的处理,以及其他一些注解相关的功能。
@Transactional() 等价于
<!-- 通知--> <tx:advice id="myAdvice" transaction-manager="transaction"> tx:attributes <!-- 哪些方法被增强--> <tx:method name="transfer" isolation="READ_COMMITTED" propagation="REQUIRED" read-only="false" 因为转账肯定需要修改 所以不是只读 /> /tx:attributes /tx:advice <!-- 配置事务的aop织入--> aop:config <aop:advisor advice-ref="myAdvice" pointcut="execution(* service.Impl.accountServiceImpl.*(..))"/> /aop:config </beans>
总结
转账这个例子 就是主动设计的错误是脏读 如果转账时出现网络 错误 一方转出了钱 ,一方没有收到钱,此时是不合理的,所以需要事务管理
相关文章:
spring事务管理快速入门(以转账为例)
spring事务管理(以转账为例) 概述 Spring事务管理提供了一种在应用程序中管理事务的机制,它抽象了底层的事务管理细节,使得开发者可以更加专注于业务逻辑的实现,而不必过多关心事务的处理。以下是Spring事务管理的一…...

如何在VS2022上的MFC项目中操作Excel(VS2010、VS2012、VS2015、VS2017、VS2019使用方法一样)
先决条件 本机安装office2003、2007、2010、2016及以后版本,总之必须安装office导入Excel库文件,导入方式可参考: 如何在vs2017及以前版本(vs2010、vs2015)上添加 添加类型库中的MFC类如何在vs2019及以后版本(如vs2022)上添加 添加ActiveX控…...

【Java8系列06】Java8数据计算
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

Andrioid T 实现充电动画(2)
Andrioid T 实现充电动画(2) 以MTK平台为例,实现充电动画 效果图 资源包 修改文件清单 system/vendor/mediatek/proprietary/packages/apps/SystemUI/res/layout/prize_charge_layout.xmlsystem/vendor/mediatek/proprietary/packages/ap…...

静态方法和属性的经典使用-单例设计模式
单例设计模式 一、设计模式二、单例模式1、饿汉式2、懒汉式3、区别 单例设计模式是静态方法和属性的经典使用。 一、设计模式 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式就像是经典的棋谱,不同的棋局&…...

TCP七层协议
物理层 中间的物理链接可以是光缆、电缆、双绞线、无线电波。中间传的是电信号,即010101...这些二进制位。 比特(bit)是二进制(Binary Digit)的简称,电脑所有的信息都是二进制的,就是0和1组成的。 数据链路层 早期…...

规则引擎Drools使用,0基础入门规则引擎Drools(五)实战+决策表
文章目录 系列文章索引十、个人所得税计算器实战1、名词解释2、计算规则3、实现步骤 十一、信用卡申请实战1、计算规则2、实现 十二、保险产品准入规则实战1、决策表2、基于决策表的入门案例3、保险产品规则介绍4、实现步骤5、资料 系列文章索引 规则引擎Drools使用࿰…...

Java后端开发——MVC商品管理程序
Java后端开发——MVC商品管理程序 本篇文章内容主要有下面几个部分: MVC架构介绍项目环境搭建商品管理模块Servlet代码重构BaseServlet文件上传 MVC 是模型-视图-控制器(Model-View-Controller),它是一种设计模式,也…...

【隐私计算】VOLE (Vector Oblivious Linear Evaluation)学习笔记
近年来,VOLE(向量不经意线性评估)被用于构造各种高效安全多方计算协议,具有较低的通信复杂度。最近的CipherGPT则是基于VOLE对线性层进行计算。 1 VOLE总体设计 VOLE的功能如下,VOLE发送 Δ \Delta Δ和 b b b给send…...

国产linux单用户模式破解无密码登陆 (麒麟系统用户登录密码遗忘解决办法)
笔者手里有一批国产linu系统,目前开始用在日常的工作生产环境中,我这个老程序猿勉为其难的充当运维的或网管的角色。 国产linux系统常见的为麒麟Linux,统信UOS等,基本都是基于debian再开发的linux。 问题描述: 因为…...

GPT市场将取代插件商店 openAI已经关闭plugins申请,全部集成到GPTs(Actions)来连接现实世界,可以与物理世界互动了。
Actions使用了plugins的许多核心思想,也增加了新的特性。 ChatGPT的"Actions"与"Plugins"是OpenAI在GPT模型中引入的两种不同的功能扩展机制。这两种机制的目的是增强模型的功能,使其能够处理更多样化的任务和请求。下面是对两者的比…...
PHP定义的变量 常量 静态变量等储存在内存什么位置?
在 PHP 中,变量、常量和静态变量都存储在内存中。它们的存储位置和生命周期有所不同。 变量:PHP 中的变量是动态类型的,它们的值和类型可以随时改变。当 PHP 脚本执行时,会在内存中分配一块空间来存储变量的值,这个空…...

C#中GDI+绘图应用(柱形图、折线图和饼形图)
目录 一、柱形图 1.示例源码 2.生成效果 二、折线图 1.示例源码 2.生成效果 三、饼形图 1.示例源码 2.生成效果 GDI绘制的一些常用的图形,其中包括柱形图、折线图和饼形图。 一、柱形图 柱形图也称为条形图,是程序开发中比较常用的一种图表技术…...

连锁零售企业如何提高异地组网的稳定性?
随着数字化时代的到来,连锁零售企业面临着日益复杂和多样化的网络挑战。连锁零售企业是在不同地理位置拥有分支机构和零售店,可能同城或异地,需要确保各个地点之间的网络连接稳定和可靠。但由于不同地区的网络基础设施差异、网络延迟和带宽限…...

如何靠掌握自己的大数据打破信息流的壁垒?
在当今数字化时代,打造自己的私域流量已经成为商家乃至获取竞争优势的关键手段之一。通过掌握自己的大数据,可以更好地了解用户需求和市场趋势,优化产品和服务,从而打破信息流的壁垒。本文将就如何通过打造自己的私域流量并掌握大…...

LabVIEW绘制带有多个不同标尺的波形图
LabVIEW绘制带有多个不同标尺的波形图 通过在同一波形图上使用多个轴,可以使用不同的标尺绘制数据。请按照以下步骤操作。 将波形图或图表控件放在前面板上。 1. 右键点击您要创建多个标尺的轴,然后选择复制标尺。例如,如果要为一个…...
Oracle行转列,列转行使用实例
-----1.行转换为列 select a.fworkcenter as 车间,F1||-数量 as 类型, fspec as 规格 ,ftype as 前缀 , to_char(fdate,YYYY-MM-dd) as 日期, (case when a.fcode in (900,901) then to_char(fcount,fm90.990) else cast(fcount as varchar(20)) end) 值 , …...

056-第三代软件开发-软件打包
第三代软件开发-软件打包 文章目录 第三代软件开发-软件打包项目介绍软件打包1 下载 linuxdepoyqt 工具2 安装 linuxdepoyqt3 qmake配置4 打包程序 总结 关键字: Qt、 Qml、 linuxdeployqt、 Ubuntu、 AppImage 项目介绍 欢迎来到我们的 QML & C 项目&…...

C++相关闲碎记录(2)
1、误用shared_ptr int* p new int; shared_ptr<int> sp1(p); shared_ptr<int> sp2(p); //error // 通过原始指针两次创建shared_ptr是错误的shared_ptr<int> sp1(new int); shared_ptr<int> sp2(sp1); //ok 如果对C相关闲碎记录(1)中记录的shar…...

如何快速搭建一个大模型?简单的UI实现
🔥博客主页:真的睡不醒 🚀系列专栏:深度学习环境搭建、环境配置问题解决、自然语言处理、语音信号处理、项目开发 💘每日语录:相信自己,一路风景一路歌,人生之美,正在于…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...