九、Spring 声明式事务学习总结

news2024/11/27 18:48:41

文章目录

  • 一、声明式事务
    • 1.1 什么是事务
    • 1.2 事务的应用场景
    • 1.3 事务的特性(ACID)
    • 1.4 未使用事务的代码示例
    • 1.5 配置 Spring 声明式事务学习总结



一、声明式事务


1.1 什么是事务

  • 把一组业务当成一个业务来做;要么都成功,要么都失败!

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


1.2 事务的应用场景

  • 在我们日常开发中,具体的业务大多数都是操作数据库的增删改查,其中包含了很多原子性的数据库操作。当同一个业务中出现多个原子性的数据库操作时,为了数据的安全性,避免数据不同步的状况发生就需要用到事务。

    • 举个栗子,银行转账

      • 两个人来到银行进行转账的操作,A 需要转给 B 1000块钱,也就是 A 的钱减少一千,B 的钱增加一千。但是如果在转账途中,出现银行系统崩溃或者网络故障等状况导致 A 的钱确实是少了一千,但是 B 的钱并没有增加,这显然是不对的。这时候事务的功效就显示出来了,两个操作要么就都成功,要么直接事务回滚,让操作都失败,以此来保证数据的安全性和一致性。



1.3 事务的特性(ACID)

  • 原子性(Atomicity):事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;

  • 一致性(Consistency):执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;

  • 隔离性(Isolation):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;

  • 持久性(Durability):一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

只有保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。也就是说 A、I、D 是手段,C 是目的!



1.4 未使用事务的代码示例

  • 项目背景 Spring + Mybatis ,将第八章的项目原封不动的粘过来,修改 mapper.xml ,将删除 SQL 改成错误的写法其他内容不变

  • 修改测试类(新增一条数据,在将这条数据删除)

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = "classpath:spring-config.xml")
    public class Test_SpringMyBatis {
    
        @Autowired
        private UsersMapper userMapper;
    
        @Test
        public void testFindUserList(){
            Users users = new Users();
            users.setId("4");
            users.setName("姚青");
            users.setPwd("123456");
            int i = userMapper.saveUser(users);
            int i3 = userMapper.deleteUsers(users);
    
        }
    
    }
    
  • 执行结果,可以看出执行到 delete 方法时候报错了,但是第一条新增添加成功了,这显然不是很合理
    在这里插入图片描述

在这里插入图片描述



1.5 配置 Spring 声明式事务学习总结

  • 上面的代码执行出来的结果明显是不符合真实情况的,所有这里需要配置 Spring 的声明式事务

    • 在 Spring 配置文件中新增配置

      • 使用Spring管理事务,需要导入头文件的约束 : tx

        xmlns:tx="http://www.springframework.org/schema/tx"
        
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">
        
      • 配置 Spring 声明式事务

         <!-- 配置 Spring 声明式事务 -->
            <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <constructor-arg ref="dataSource"/>
            </bean>
        
      • 配置好声明式事务之后,结合 Spring aop 实现事务的织入(这里需要引入 tx (事务))

        <!-- 结合 Spring aop 实现事务的织入 -->
        <!-- 第一步:配置事务通知 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <!-- 给那些方法配置事务,可以是具体的方法名,也可以是*,*代表所有方法 -->
            <!--配置事务的传播特性: new propagation-->
            <tx:attributes>
                <tx:method name="add" propagation="REQUIRED"/>
                <tx:method name="delete" propagation="REQUIRED"/>
                <tx:method name="update" propagation="REQUIRED"/>
                <tx:method name="query" read-only="true"/>
                <tx:method name="*" propagation="REQUIRED"/>
            </tx:attributes>
        </tx:advice>
        
        <!-- 第二步:配置事务切入 -->
        <aop:config>
            <!-- 指定切入点为 mapper 包下所有接口中的所有方法 -->
            <aop:pointcut id="txPointCut" expression="execution(* com.sys.mapper.*.*(..))"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
        </aop:config>
        
    • Spring 完整配置

      <?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/beans
              http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/context
              http://www.springframework.org/schema/context/spring-context.xsd
              http://www.springframework.org/schema/tx
              http://www.springframework.org/schema/tx/spring-tx.xsd
              http://www.springframework.org/schema/aop
              https://www.springframework.org/schema/aop/spring-aop.xsd">
      
          <!-- 加载数据库连接信息的属性文件 -->
          <context:property-placeholder location="classpath:jdbc-config.properties"/>
      
          <!-- 配置Druid数据源的Bean -->
          <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
              <property name="driverClassName" value="${jdbc.driver}"/>
              <property name="url" value="${jdbc.url}"/>
              <property name="username" value="${jdbc.username}"/>
              <property name="password" value="${jdbc.password}"/>
          </bean>
      
          <!-- 配置SessionFactory的Bean -->
          <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
              <!-- 注入数据源 -->
              <property name="dataSource" ref="dataSource"/>
              <!-- 指定MyBatis配置文件的位置 -->
              <property name="configLocation" value="classpath:mybatis-config.xml"/>
              <!-- 配置 xml 的映射 -->
              <property name="mapperLocations" value="classpath:mapper/*.xml"/>
          </bean>
      
          <!-- 配置mapper接口的扫描器,将Mapper接口的实现类自动注入到IoC容器中
           实现类Bean的名称默认为接口类名的首字母小写 -->
          <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
              <!-- basePackage属性指定自动扫描mapper接口所在的包 -->
              <property name="basePackage" value="com.sys.mapper"/>
          </bean>
      
          <!-- 配置 Spring 声明式事务 -->
          <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
              <constructor-arg ref="dataSource"/>
          </bean>
      
          <!-- 结合 Spring aop 实现事务的织入 -->
          <!-- 第一步:配置事务通知 -->
          <tx:advice id="txAdvice" transaction-manager="transactionManager">
              <!-- 给那些方法配置事务,可以是具体的方法名,也可以是*,*代表所有方法 -->
              <!--配置事务的传播特性: new propagation-->
              <tx:attributes>
                  <tx:method name="add" propagation="REQUIRED"/>
                  <tx:method name="delete" propagation="REQUIRED"/>
                  <tx:method name="update" propagation="REQUIRED"/>
                  <tx:method name="query" read-only="true"/>
                  <tx:method name="*" propagation="REQUIRED"/>
              </tx:attributes>
          </tx:advice>
      
          <!-- 第二步:配置事务切入 -->
          <aop:config>
              <!-- 指定切入点为 mapper 包下所有接口中的所有方法 -->
              <aop:pointcut id="txPointCut" expression="execution(* com.sys.mapper.*.*(..))"/>
              <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
          </aop:config>
      
      </beans>
      
  • 其他代码不变

    • 测试结果:执行到 delete 方法时,依然报错,但是数据库没有新增数据,事务回滚成功。

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

宋浩概率论笔记(四)数字特征

本帖更新数字特征&#xff0c;包含期望、方差、相关系数等&#xff0c;要点在于记忆性质中的各种公式&#xff0c;遇到题目时能迅速利用已知条件计算答案。

Bigemap如何添加谷歌地图?

工具 Bigemap gis office地图软件 BIGEMAP GIS Office-全能版 Bigemap APP_卫星地图APP_高清卫星地图APP 打开软件&#xff0c;要提示需要授权和添加地图&#xff0c;然后去点击选择地图这个按钮&#xff0c;列表中有个添加按钮点进去选择添加地图的方式。 第一种方式&#x…

飞凌OKMX6ULL-C开发板试用

开箱体验 主要配件包括&#xff1a;USB Type-C调试线、电源线、主板。 资源下载 开发环境 飞凌提供了制作好的ubuntu18.04的镜像&#xff0c;直接到网盘下载解压即可&#xff0c;VMWare的安装可以参考网上教程&#xff0c;这里不赘述。安装好VMWare后直接打开解压出来的ubu…

macos搭建python3虚拟环境

我们知道macos自带的python版本是Python2.7, 这个版本比较老而且往往和我们的工程不兼容&#xff0c;所以就得需要我们升级Python版本&#xff0c; 我们不建议直接升级macos自带的本地Python2.7, 因为macos有一些基础软件是依赖于Python2.7的&#xff0c;如果动了遇到问题想再…

neo4j入门实例介绍

使用Cypher查询语言创建了一个图数据库&#xff0c;其中包含了电影《The Matrix》和演员Keanu Reeves、Carrie-Anne Moss、Laurence Fishburne、Hugo Weaving以及导演Lilly Wachowski和Lana Wachowski之间的关系。 CREATE (TheMatrix:Movie {title:The Matrix, released:1999,…

力扣:54. 螺旋矩阵(Python3)

题目&#xff1a; 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;力扣 示例&#xff1a; 示例 1&#xff1a; 输入&#xff1a;matrix [[1,…

[NOIP2007 普及组] 纪念品分组

[NOIP2007 普及组] 纪念品分组 题目描述 元旦快到了&#xff0c;校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得 的纪念品价值相对均衡&#xff0c;他要把购来的纪念品根据价格进行分组&#xff0c;但每组最多只能包括两件纪念品&#xff0c; 并且…

IO学习-线程

1&#xff0c;使用信号量的方式实现&#xff0c;将倒置以及打印的那道题目&#xff0c; 要求打印&#xff0c;倒置线程&#xff0c;顺序执行。出现的现象为先打印1234567&#xff0c;后打印7654321 不使用flag 运行结果&#xff1a; 2&#xff0c;创建两个线程&#xff0c;其中…

3. C++类和对象

一、面向对象程序设计的基本特点 1.1 抽象 指对具体问题&#xff08;对象&#xff09;进行概括&#xff0c;抽出一类对象的公共性质并加以描述的过程 数据抽象 描述某类对象的属性或状态&#xff0c;即此类对象与其他类对象的区别 行为抽象 描述某类对象的共同行为或功能特征…

IP核之fifo

一.FIFO简介 FIFO (First In First Out&#xff0c;即先入先出&#xff09;&#xff0c;是一种数据缓冲器&#xff0c;用来实现数据先入先出的读写方式。 二&#xff0c;FIFO实现原理 FIFO是采用一种先入先出的实现原理 就如图按照D1到D10的顺序输入那么读取的时候也是按照D…

web浏览器打开本地exe应用

一、如何使web浏览器打开本地exe应用&#xff1f; 浏览器打开本地exe程序我们可以使用ActiveXObject方法&#xff0c;但是只支持IE&#xff0c;谷歌、火狐等浏览器并不支持此操作。 那问题来了&#xff0c;我们又该如何操作&#xff1f; 经过本博主的不断学习探索终于找到了一…

多语言一键铺货跨境电商平台快速开发(java开源)

要搭建一个多语言一键铺货跨境电商平台&#xff0c;可以参考以下步骤&#xff1a; 1. 确定需求&#xff1a;首先&#xff0c;明确平台的功能需求&#xff0c;包括多语言支持、一键铺货功能、跨境支付等。 2. 选择适合的开源项目&#xff1a;选择一个适合的Java开源电商平台项…

Unity 编辑器资源导入处理函数 OnPreprocessAudio :深入解析与实用案例

Unity 编辑器资源导入处理函数 OnPreprocessAudio 用法 点击封面跳转下载页面 简介 在 Unity 中&#xff0c;资源导入是一个非常重要的环节&#xff0c;它决定了资源在项目中的使用方式和效果。Unity 提供了一系列的资源导入处理函数&#xff0c;其中之一就是 OnPreprocessAud…

Crond计划任务的简单使用

目录 前言 一、一次性任务at 二、crond周期性任务 总结 前言 crond是Linux系统中的一个守护进程&#xff0c;负责定期执行预设的任务&#xff0c;也称为计划任务。它可以根据用户的需求&#xff0c;在指定的时间、日期或周期性地执行特定的命令或本crond的用是自动化和定时执行…

JavaWeb_LeadNews_Day5-文章定时发布

JavaWeb_LeadNews_Day5-文章定时发布 延时服务概述DelayQueueRabbitMQ(常用)Redis(常用) redis延迟服务实现思路总思路添加任务取消任务拉取任务未来数据定时刷新redis解决集群抢占 具体实现乐观锁docker运行redis项目集成redis添加任务取消任务拉取任务未来数据定时刷新redis解…

Jmeter入门之digest函数 jmeter字符串连接与登录串加密应用

登录请求中加密串是由多个子串连接&#xff0c;再加密之后传输。 参数连接&#xff1a;${var1}${var2}${var3} 加密函数&#xff1a;__digest &#xff08;函数助手里如果没有该函数&#xff0c;请下载最新版本的jmeter5.0&#xff09; 函数助手&#xff1a;Options > …

【Hystrix技术指南】(1)基本使用和配置说明

这世间许多事物皆因相信而存在&#xff0c;所以人们亲手捏出了泥菩萨&#xff0c;却选择坚定的去信仰它。 分布式系统的规模和复杂度不断增加&#xff0c;随着而来的是对分布式系统可用性的要求越来越高。在各种高可用设计模式中&#xff0c;【熔断、隔离、降级、限流】是经常被…

wordpress日主题Ripro9.0最新二开修正源码下载+美化包和插件

日主题Ripro9.0最新二开升级修正源码美化包和插件&#xff0c;RiPro9.0的二开版本新模板&#xff0c;包含2个美化包和全屏水印以及防复制插件。 模板和美化包路径:\wp-content\themes 插件路径&#xff1a;\wp-content\plugins&#xff0c;有兴趣的自行去体验吧

AOP-AspectJ 切面技术及使用MethodInterceptor实现切面

目录 一、简介 二、什么是AspectJ AOP 思想概述 AOP 实现方式 AOP 特性概念 切点指示器 通知类型 三、实现AOP的方式 四、配置说明 自定义注解作为切点 NeedCut MyAop GirlController 继承MethodInterceptor实现切面 MyMethodInterceptor AopConfig NeedCut 注解…

如何将安卓 Gradle 模块打包发布到本地 Maven 仓库

文章目录 具体流程 笔者的运行环境&#xff1a; Android Studio Flamingo | 2022.2.1 Android SDK 33 Gradle 8.0.1 JDK 17 Android 的 Gradle 项目与一般的 Gradle 项目是不同的&#xff0c;因此对将 Gradle 模块打包发布到本地 Maven 仓库来说&#xff0c;对普通 Gradle …