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

Spring——Spring中基于注解以及配置实现事务的管理

Spring事务管理总结目录

  • 1. Spring事务管理的前置知识
    • 1.1 Spring 的事务管理
    • 1.2 Spring中事务的五大隔离级别
    • 1.3 Spring事务的传播特性
    • 1.4 @Transactional的参数讲解
  • 2. Spring中实现事务
    • 2.1 基于注解方式实现事务【了解】
      • 2.1.1 导入相关依赖
      • 2.1.2 配置注解驱动
      • 2.1.3 在相关方法或者类中加入@Transactional设置传播特性
    • 2.2 声明式事务【重点,需要掌握】
      • 2.2.1 要求项目中的方法命名有规范
      • 2.2.2 添加事务管理器配置切面以及绑定

1. Spring事务管理的前置知识

Spring整合Mybatis
    将 MyBatis 与 Spring 进行整合,主要解决的问题就是将 SqlSessionFactory 对象交由 Spring 来管理。所以,该整合只需要将 SqlSessionFactory 的对象生成器SqlSessionFactoryBean 注册在 Spring 容器中,再将其注入给 Dao 的实现类即可完成整合。
    实现 Spring 与 MyBatis 的整合。常用的方式:扫描的 Mapper 动态代理。Spring 像插线板一样,mybatis 框架是插头,可以容易的组合到一起。插线板 spring 插上 mybatis,两个框架就是一个整体。

1.1 Spring 的事务管理

    事务原本是数据库中的概念,在实际项目的开发中,进行事务的处理一般是在业务逻辑层, 即 Service 层。这样做是为了能够使用事务的特性来管理关联操作的业务。
    在 Spring 中通常可以通过以下两种方式来实现对事务的管理:

Ⅰ 使用 Spring 的事务注解管理事务
Ⅱ 使用 AspectJ 的 AOP 配置管理事务(声明式事务管理)

1.2 Spring中事务的五大隔离级别

Ⅰ 未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
Ⅱ 提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
Ⅲ 可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读,但是innoDB解决了幻读
Ⅳ 串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
Ⅴ 使用数据库默认的隔离级别isolation = Isolation.DEFAULT
MySQL:mysql默认的事务处理级别是’REPEATABLE-READ’,也就是可重复读
Oracle:oracle数据库支持READ COMMITTED 和 SERIALIZABLE这两种事务隔离级别。默认系统事务隔离级别是READ COMMITTED,也就是读已提交

1.3 Spring事务的传播特性

多个事务之间的合并,互斥等都可以通过设置事务的传播特性来解决.

常用

PROPAGATION_REQUIRED:必被包含事务(增删改必用)
PROPAGATION_REQUIRES_NEW:自己新开事务,不管之前是否有事务【将正在执行的A的事务挂起,然后执行自己新开的B事务,执行完毕之后,继续执行B事务】
PROPAGATION_SUPPORTS:支持事务,如果加入的方法有事务,则支持事务,如果没有,不单开事务【例如A事务是REQUIRERD类型的,那么B事务进来后也会表成REQUIRED,】
PROPAGATION_NEVER:不能运行中事务中,如果包在事务中,抛异常
PROPAGATION_NOT_SUPPORTED:不支持事务,运行在非事务的环境【将正在执行的A的事务挂起,然后执行自己新开的B事务,执行完毕之后,继续执行B事务】

不常用

PROPAGATION_MANDATORY:必须包在事务中,没有事务则抛异常
PROPAGATION_NESTED:嵌套事务

1.4 @Transactional的参数讲解

【了解,一般使用声明式事务的方式】
①propagation = Propagation.REQUIRED,//事务的传播特性
②noRollbackForClassName = “ArithmeticException”, //指定发生什么异常不回滚,使用的是异常的名称
③noRollbackFor = ArithmeticException.class,//指定发生什么异常不回滚,使用的是异常的类型
④rollbackForClassName = “”,//指定发生什么异常必须回滚
⑤rollbackFor = ArithmeticException.class,//指定发生什么异常必须回滚
⑥timeout = -1, //连接超时设置,默认值是-1,表示永不超时
⑦readOnly = false, //默认是false,如果是查询操作,必须设置为true.
⑧ isolation = Isolation.DEFAULT//使用数据库自已的隔离级别

2. Spring中实现事务

2.1 基于注解方式实现事务【了解】

  • 使用此方法不够灵活,每个方法执行操作不同,需要的事务特性也不同
    • 在增删改业务方法中需要添加事务
    • 在查找业务中需要将readonly设置为true
  • 所以还不能将注解配置在类上,需要配置在方法上,这样显得特别麻烦,不像声明式事务的方式,只需要配置xml文件:实现添加事务管理器,配置切面,以及绑定切面和切入点即可

2.1.1 导入相关依赖

 <dependencies>
    <!--单元测试-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <!--aspectj依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    <!--spring核心ioc-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    <!--做spring事务用到的-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    <!--mybatis依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.6</version>
    </dependency>
    <!--mybatis和spring集成的依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.1</version>
    </dependency>
    <!--mysql驱动-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.29</version>
    </dependency>
    <!--阿里公司的数据库连接池-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.12</version>
    </dependency>
  </dependencies>

  <build>
    <!--目的是把src/main/java目录中的xml文件包含到输出结果中。输出到classes目录中-->
    <resources>
      <resource>
        <directory>src/main/java</directory><!--所在的目录-->
        <includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
      <resource>
        <directory>src/main/resources</directory><!--所在的目录-->
        <includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
  </build>

2.1.2 配置注解驱动

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--配置数据源,事务必须关联数据库处理-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--添加注解驱动-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

2.1.3 在相关方法或者类中加入@Transactional设置传播特性

在这里插入图片描述

2.2 声明式事务【重点,需要掌握】

  • 使用此方法在程序中不需要添加任何的事务管理,所有的配置都在xml文件中处理

2.2.1 要求项目中的方法命名有规范

  • 完成增加操作包含 add save insert set
  • 更新操作包含 update change modify
  • 删除操作包含 delete drop remove clear
  • 查询操作包含 select find search get

2.2.2 添加事务管理器配置切面以及绑定

    添加事务管理器的原因:事务管理器用来生成相应技术的连接+执行语句的对象. 如果使用MyBatis框架,必须使用DataSourceTransactionManager类完成处理

  下面是不同方式实现对数据库的操作对象

JDBC: Connection con.commit(); con.rollback();
MyBatis: SqlSession sqlSession.commit(); sqlSession.rollback();
Hibernate: Session session.commit(); session.rollback();

 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!--因为事务必须关联数据库处理,所以要配置数据源-->
    <property name="dataSource" ref="dataSource"></property>
 </bean>

配置事务切面时可以使用通配符*来匹配所有方法

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

    <!--配置事务切面-->
    <tx:advice id="myadvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*select*" read-only="true"/>
            <tx:method name="*find*" read-only="true"/>
            <tx:method name="*search*" read-only="true"/>
            <tx:method name="*get*" read-only="true"/>
            <tx:method name="*insert*" propagation="REQUIRED" no-rollback-for="ArithmeticException"/>
            <tx:method name="*add*" propagation="REQUIRED"/>
            <tx:method name="*save*" propagation="REQUIRED" no-rollback-for="ArithmeticException"/>
            <tx:method name="*set*" propagation="REQUIRED"/>
            <tx:method name="*update*" propagation="REQUIRED"/>
            <tx:method name="*change*" propagation="REQUIRED"/>
            <tx:method name="*modify*" propagation="REQUIRED"/>
            <tx:method name="*delete*" propagation="REQUIRED"/>
            <tx:method name="*remove*" propagation="REQUIRED"/>
            <tx:method name="*drop*" propagation="REQUIRED"/>
            <tx:method name="*clear*" propagation="REQUIRED"/>
            <tx:method name="*" propagation="SUPPORTS"/>
        </tx:attributes>
    </tx:advice>
    <!--绑定切面和切入点-->
    <aop:config>
        <aop:pointcut id="mycut" expression="execution(* com.bjpowernode.service.impl.*.*(..))"></aop:pointcut>
        <aop:advisor  advice-ref="myadvice" pointcut-ref="mycut"></aop:advisor>
    </aop:config>

相关文章:

  • JavaScript基础 JavaScript第二天 2. 语句
  • 【Python零基础入门篇 · 6】:Python中的注释、字符串的常见操作、对象的布尔值
  • 【填坑】ESP32-C3 bootloader开发(上)
  • SPI通信总线
  • STC15单片机-看门狗介绍
  • C/C++教程 从入门到精通《第二十二章》——Qt控件详解
  • ECCV 2022 | k-means Mask Transformer
  • 如何做顶级“新生代农民工”?这几本书为你打开大门
  • datawhale8月组队学习《pandas数据处理与分析》(下)(文本、分类、时序数据)
  • 王道书 P191 思维拓展
  • matplotlib与django如何集成? matplotlib生成的图可以嵌入到网页吗?
  • 内卷室友系列 -- day01 计算机网络概论
  • mac显示器如何显示docker container中的gui请求
  • SpringCloud 三种服务调用方式详解
  • SpringCloud 三种服务调用方式,你知道几种?
  • [NodeJS] 关于Buffer
  • css系列之关于字体的事
  • ES6 学习笔记(一)let,const和解构赋值
  • java2019面试题北京
  • java8-模拟hadoop
  • java第三方包学习之lombok
  • mac修复ab及siege安装
  • Mac转Windows的拯救指南
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • Service Worker
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • 程序员该如何有效的找工作?
  • 京东美团研发面经
  • 看域名解析域名安全对SEO的影响
  • 算法-插入排序
  • 网络应用优化——时延与带宽
  • 详解NodeJs流之一
  • 怎么把视频里的音乐提取出来
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • 我们雇佣了一只大猴子...
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #git 撤消对文件的更改
  • #pragma pack(1)
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (转)C#调用WebService 基础
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • *p++,*(p++),*++p,(*p)++区别?
  • .NET CLR Hosting 简介
  • .net core 6 redis操作类
  • .net Stream篇(六)