006 spring事务支持

文章目录

    • 事务回顾
      • 事务介绍
      • 事务并发问题(隔离性导致)
      • 事务隔离级别
    • Spring框架事务管理相关接口
    • Spring框架事务管理的分类
      • 编程式事务管理(了解)
      • 声明式事务管理(重点)
    • 事务管理之XML方式
      • 业务层
      • 持久层
      • 单元测试代码
      • 配置事务管理的AOP
    • 事务管理之混合方式
    • 事务管理之基于AspectJ的纯注解方式

事务回顾

事务介绍

事务:指的是逻辑上一组操作,组成这个事务的各个执行单元,要么一起成功,要么一起失败
事务的特性(ACID):

  • 原子性(Atomicity)

原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚

  • 一致性(Consistency)

一致性是指事务必须使数据库一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态
拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还是5000,这就是事务的一致性

  • 隔离性(Isolation)

隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离

  • 持久性

持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作

事务并发问题(隔离性导致)

在事务的并发操作中可能会出现一些问题

  • 脏读:一个事务读取到另一个事务未提交的数据
  • 不可重复读:一个事务因读取到另一个事务已提交的数据。导致对同一条记录读取两次以上的结果不一致
  • 幻读:一个事务因读取到另一个事务已提交的数据。导致对同一张表读取两次以上的结果不一致。insert、delete操作

事务隔离级别

为了避免上面出现的几种情况,在标注SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同

  • 四种隔离级别:
    现在来看看MySQL数据库为我们提供的四种隔离级别(由低到高):
  1. Read uncommitted(读未提交):最低级别,任何情况都无法保证
  2. Read committed(读已提交):可避免脏读的发生
  3. Repeatable read(可重复读):可避免脏读、不可重复读的发生
  4. Serializable(串行化):可避免脏读、不可重复读、幻读的发生
  • 默认隔离级别
    大多数数据库的默认隔离级别是Read Committed(RC),比如Oracle、DB2等。
    MySQL数据库的默认隔离级别是Repeatable Read(RR)

  • 注意事项

隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大

对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Comitted。它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制

Spring框架事务管理相关接口

Spring并不直接管理事务,而是提供了事务管理接口是PlatformTransactionManager,通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了
在这里插入图片描述

1.PlatformTransactionManager接口 – 平台事务管理器(真正管理事务的类)。该接口有具体的实现类,根据不同的持久层框架,需要选择不同的实现类
2.TransactionDefinition接口 – 事务定义信息(事务的隔离级别,传播行为,超时,只读)
3.TransactionStatus接口 --事务的状态(是否新事务、是否已提交、是否有保存点、是否回滚)
4.总结:上述对象之间的关系:平台事务管理器真正管理事务对象 根据事务定义的信息TransactionDefinition进行事务管理,在管理事务中产生一些状态 将状态记录到TransactionStatus中
5.PlatformTransactionManager接口中实现类和常用的方法

1.接口的实现类
如果使用的Spring的JDBC模板或者MyBatis(IBatis)框架,需要选择DataSourceTransactionManager实现类
如果使用的是Hibernate的框架,需要选择HibernateTransactionManager实现类

2.该接口的常用方法
void commit(TransactionStatus status)
TransactionStatus getTransaction(TransactionDefinition definition)
void rollback(TransactionStatus status)

6.TransactionDefinition

1.事务隔离级别的常量
static int ISOLATION_DEFAULT --采用数据库的默认隔离级别
static int ISOLATION_READ_UNCOMMITTED
static int ISOLATION_READ_COMMITTED
static int ISOLATION_REPEATABLE_READ
static int ISOLATION_SERIALIZABLE

2.事务的传播行为常量(不用设置,使用默认值)
先解释什么是事务的传播行为:解决的是业务层之间的方法调用
PROPAGATION_REQUIRED(默认值) – A中有事务,使用A中的事务。如果没有,B就会开启一个新的事务,将A包含进来。(保证A,B在同一个事务中),默认值
PROPAGATION_SUPPORTS – A中有事务,使用A中的事务。如果A中没有事务,那么B也不使用事务。
PROPAGATION_MANDATOTY – A中有事务,使用A中的事务。如果A没有事务,抛出异常
PROPAGATION_REQUIRES_NEW – A中有事务,将A中的事务挂起。B创建一个新的事务(保证A,B没有在一个事务中)
PROPAGATION_NOT_SUPPORTED – A中有事务,将A中的事务挂起
PROPAGATION_NEVER --A中有事务,抛出异常
PROPAGATION_NESTED --嵌套事务。当A执行之后,就会在这个位置设置一个保存点。如果B没有问题,执行通过。如果B出现异常,运行客户根据需求回滚(选择回滚到保存点或者最初始状态)

Spring框架事务管理的分类

1.Spring的编程式事务管理(不推荐使用)

通过手动编写代码的方式完成事务的管理(不推荐)

2.Spring的声明式事务管理(底层采用AOP的技术)

通过一段配置的方式完成事务的管理

编程式事务管理(了解)

说明:Spring为了简化事务管理的代码:提供了模板类TransactionTemplate,所以手动编程的方式来管理事务,只需要使用该模板类即可
手动编程方式的具体步骤如下:
1.步骤一:配置一个事务管理器,Spring使用PlatformTransactionManager接口来管理事务,所以需要使用到他的实现类

<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/>
</bean>

2.步骤二:配置事务管理的模板

<!--配置事务管理的模板-->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"><property name="transactionManager" ref="transactionManager"/>
</bean>

3.步骤三:在需要进行事务管理的类中,注入事务管理的模板

<bean id="accountService" class="com.spring.service.AccountServiceImpl"><property name="accountDao" ref="accountDao"/><property name="transactionTemplate" ref="transactionTemplate" />
</bean>

4.步骤四:在业务层使用模板管理事务

//注入事务模板对象
private TransactionTemplate transactionTemplate;
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {this.transactionTemplate = transactionTemplate;
}public void pay(final String out, final String in, final double money) {transactionTemplate.execute(new TransactionCallbackWithoutResult(){protected void doInTransactionWithoutResult(TransactionStatus status) {//扣钱accountDao.outMoney(out,money);int a = 10/0;//加钱accountDao.inMoney(in,money);}});
}

声明式事务管理(重点)

声明式事务管理又分成三种方式

  • 基于AspectJ的XML方式(重点掌握)
  • 基于AspectJ的注解+XML混用方式(重点掌握)
  • 基于AspectJ的纯注解方式(重点掌握)

事务管理之XML方式

准备转账环境:

业务层

AccountService
AccountServiceImpl
public void transfer(String in, String out, double money) {dao.outMoney(out,money);//异常代码System.out.println(1/0);dao.inMoney(in,money);
}

持久层

AccountDao
AccountDaoImpl

spring配置

<!--配置数据源连接池(C3P0) -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"><property name="driverClass" value="com.mysql.jdbc.Driver" /><property name="jdbcUrl" value="jdbc:mysql:///web01" /><property name="user" value="root" /><property name="password" value="root" />
</bean><bean class="cn.spring.dao.AccountDaoImpl"><property name="dataSource" ref="dataSource"></property>
</bean><context:component-scan base-package="cn.spring.service"></context:component-scan>

单元测试代码


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(location={"classpath:applicationContext-tx.xml"})
public class TransactionTest {@Autowiredprivate AccountService service;@Testpublic void test01() {service.transfer("a","b",100);}
}

配置事务管理的AOP

  • 平台事务管理器:DataSourceTransactionManager
<!-- 配置平台事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!--注入数据源--><property name="dataSource" ref="dataSource"></property>
</bean>
  • 事务通知

<tx:advice id=“” transaction-manager=“” />

<tx:advice id="txAdvice" transaction-manager="transactionManager"><!-- 配置事务相关属性 --><tx:attributes><!-- 对方法级别设置 事务的隔离级别、事务的传播行为--><!-- 设置了默认的隔离级别和传播行为--><tx:method name="transfer" /><!-- 提交订单--><tx:method name="submitOrder" /><!-- 添加 --><tx:method name="add*" /><tx:method name="insert*" /><!-- 删除 --><tx:method name="delete*" /><tx:method name="remove*" /><!-- 修改 --><tx:method name="update*" /><tx:method name="modify*" /><!-- 查询 --><tx:method name="find*" read-only="true" /><tx:method name="get*" read-only="true" /><tx:method name="query*" read-only="true" /></tx:attributes></tx:advice>
  • AOP配置:
<aop:config><aop:advisor advice-ref="" pointcut=""/>
</aop:config>
<!--配置AOP-->
<aop:config><!--切入点:所有的业务层实现类中方法--><aop:advisor advice-ref="txAdvice" pointcut="execution(* cn..service.*.*(..))"/></aop:config>

事务管理之混合方式

  • service类上或方法上加注解:

类上加@Transactional:表示该类中所有的方法都被事务管理
方法上加@Transactional:表示只有该方法被事务管理

  • 开启事务注解:
<!-- 配置平台事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!--注入数据源--><property name="dataSource" ref="dataSource"></property></bean><!-- 开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

事务管理之基于AspectJ的纯注解方式

@EnableTransactionManagement

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

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

相关文章

Matlab只选取自己需要的数据画图

在Matlab作图的时候&#xff0c;经常会在同一个坐标系中作很多数据的图&#xff0c;如下图所示&#xff1a; 这就会导致不同数据所作的线会重叠在一起&#xff0c;不利于数据分析。如果只想对比几个数据的趋势&#xff0c;直接修改代码太过麻烦&#xff0c;可通过Matlab的绘图…

springboot项目mapper无法自动装配,未找到 ‘userMapper‘ 类型的Bean解决办法.

一开始我看到了这个回答&#xff1a;springboot项目mapper无法自动装配&#xff0c;未找到 ‘userMapper‘ 类型的 Bean解决办法&#xff08;含报错原因&#xff09;_无法自动装配。找不到 usermapper 类型的 bean。-CSDN博客 mapper无法自动装配&#xff0c;未找到 ‘userMap…

python+unity手势控制地球大小

效果图如下 具体操作如下 1 在unity窗口添加一个球体 2 给球体添加材质,材质图片使用地球图片 地球图片如下 unity材质设置截图如下 3 编写地球控制脚本 using System.Collections; using System.Collections.Generic; using UnityEngine;public class test : MonoBehavio…

【AI绘画】新手小白看这篇就够啦!国产PS AI插件超好入门!

随着人工智能技术的飞速发展&#xff0c;Photoshop作为设计师们不可或缺的工具&#xff0c;也在不断地融入AI技术&#xff0c;以提升设计效率和效果。最近米兔用了一款AI绘画软件StartAI&#xff0c;被其强大的功能和易用性经验到了&#xff0c;下面跟大家详细分享一下这款ps插…

ViNT: A Foundation Model for Visual Navigation

介绍 现存的问题&#xff1a;预训练的方式在很多领域取得了成功&#xff0c;但是由于环境、平台和应用程序的绝对多样性&#xff0c;因此很难应用在机器人领域。 那么想要做移动机器人的基础模型需要什么&#xff1f; 本文定义了一个机器人领域的基础模型&#xff0c;可以实…

电脑数据恢复,掌握4个方法,恢复数据很简单!

在数字化浪潮席卷全球的今天&#xff0c;电脑数据已成为我们生活与工作中不可或缺的一部分。然而&#xff0c;当这些数据因各种原因意外丢失或损坏时&#xff0c;那种失落与无助的感觉常常令人倍感焦虑。 想象一下&#xff0c;你正在为一项重要项目加班加点&#xff0c;突然电…

【CVPR2021】LoFTR:基于Transformers的无探测器的局部特征匹配方法

LoFTR&#xff1a;基于Transformers的局部检测器 0. 摘要 我们提出了一种新的局部图像特征匹配方法。我们建议先在粗略级别建立像素级密集匹配&#xff0c;然后再在精细级别细化良好匹配&#xff0c;而不是按顺序进行图像特征检测、描述和匹配。与使用成本体积搜索对应关系的密…

力扣hot100: 48. 旋转图像

LeetCode&#xff1a;48. 旋转图像 受到力扣hot100&#xff1a;54. 螺旋矩阵的启发&#xff0c;我们可以对旋转图像按层旋转&#xff0c;我们只需要记录四个顶点&#xff0c;并且本题是一个方阵&#xff0c;四个顶点就能完成图像的旋转操作。 1、逐层旋转 注意到&#xff0…

打造完美Mac多屏视界,BetterDisplay Pro一键掌控!

BetterDisplay Pro for Mac是一款专为Mac用户打造的显示器管理与优化软件&#xff0c;旨在为用户带来卓越的视觉体验和工作效率。它凭借强大的功能和简洁易用的界面&#xff0c;成为了Mac用户优化显示器设置的得力助手。 一、全方位管理与优化 BetterDisplay Pro for Mac支持…

0元体验苹果macOS系统,最简单的虚拟机部署macOS教程

前言 最近发现小伙伴热衷于在VMware上安装体验macOS系统&#xff0c;所以就有了今天的帖子。 正文开始 首先&#xff0c;鉴于小伙伴们热衷macOS&#xff0c;所以小白搜罗了一圈macOS系统&#xff0c;并开启了分享通道。 本次更新的系统版本是&#xff1a; macOS 10.13.6 ma…

LogicFlow 学习笔记——2. LogicFlow 基础 实例

LogicFlow 实例 创建实例 每一个流程设计界面&#xff0c;就是一个 LogicFlow 的实例。 <template><div id"container"></div><!-- 用于显示 LogicFlow 图表的容器 --> </template> <script>// 创建 LogicFlow 实例const lf …

YOLOv10改进 | 注意力篇 | YOLOv10引入Polarized Self-Attention注意力机制

1. Polarized Self-Attention介绍 1.1 摘要:像素级回归可能是细粒度计算机视觉任务中最常见的问题,例如估计关键点热图和分割掩模。 这些回归问题非常具有挑战性,特别是因为它们需要在低计算开销的情况下对高分辨率输入/输出的长期依赖性进行建模,以估计高度非线性的像素语…

什么洗地机好用又实惠?四大口碑优品推荐,超级火爆

作为一个家电工作者&#xff0c;近年来测评了不少洗地机&#xff0c;相对于传统的清洁习惯&#xff0c;即先扫地&#xff0c;再拖地&#xff0c;洗地机能够在一拖一拉之间&#xff0c;便完成地面上的清洁&#xff0c;而且人们也不用低头弯腰的去清洁&#xff0c;可谓是省时省力…

el-tree回显复选框时半选中和全选中的树

项目需求如下&#xff1a;当我点击“编辑”后&#xff0c;需要在tree树上全勾中和半勾中选项&#xff0c;由于后端接口返回的tree树是含了父级节点id的数组集合&#xff0c;所以我们回显时需要处理好这个全勾中和半勾中的问题。 主要思路如下&#xff0c;我们通过setData方法获…

专业学习|博弈论-博弈论概述

&#xff08;一&#xff09;认识博弈论&#xff1a;解析复杂决策与策略 &#xff08;1&#xff09;认识博弈 博弈论广泛应用于分析个体间因利益冲突而产生的决策问题。通过构建不同模型来探讨如经贸关系、军事威胁等问题&#xff0c;旨在寻找均衡解并提供新知&#xff0c;相较…

一个简单的信号发射电路的构建

在基本的信号发射电路中&#xff0c;线圈&#xff08;电感器&#xff09;和电阻的组合可以产生振荡信号&#xff0c;而天线&#xff08;通常通过线圈&#xff09;用于发射信号。 LC振荡电路&#xff1a; **线圈&#xff08;L1&#xff09;和电容器&#xff08;C&#xff09;**串…

【正则表达式】入门

参考视频&#xff1a;10分钟快速掌握正则表达式_哔哩哔哩_bilibili 这个网站用来测试写的正则表达式效果&#xff1a;regex101: build, test, and debug regex 示例&#xff1a; 限定符 ? 表示前一个字符可有可无 比如这里输入&#xff1a;de? 匹配结果可以得到d和de * 前…

SpringMVC—RequestMapping注解

一、RequestMapping注解 RequestMapping注解&#xff1a;是Spring MVC框架中的一个控制器映射注解&#xff0c;用于将请求映射到相应的处理方法上&#xff0c;具体来说&#xff0c;他可以将指定URL的请求绑定到一个特定的方法或类上&#xff0c;从而实现对请求的处理和响应。 …

线代的学习(矩阵)

1.矩阵的乘法 矩阵实现满足&#xff1a;内标相等 矩阵相乘之后的结果&#xff1a;前行后列 需要注意&#xff1a;1.矩阵的乘法不具有交换律&#xff1a;AB!BA 2.矩阵的乘法满足分配律&#xff1a;A(BC) AB AC 抽象逆矩阵求逆矩阵 方法1.凑定义法、 方法2.长除法 数字型矩阵…

SpringBoot快速入门-上

Apache Tomcat Apache Tomcat是一个开源的Servlet 或 web容器&#xff0c;它实现了Java Servlet、JavaServer Pages (JSP)、Java Unified Expression Language (JUEL) 和 Java WebSocket 规范。 使用 官网下载 安装:绿色版 , 直接解压 卸载:直接删除目录 改编码: # conf/l…