Spring——Spring中的事务、使用注解(@Transactional)控制事务、使用AspectJ框架控制事务 (上)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: Spring——Spring中的事务、使用注解(@Transactional)控制事务、使用AspectJ框架控制事务 (上)

文章目录:


1.事务的概念

1.1 Spring中的事务 

1.2 Spring的事务管理器 

1.3 关于事务的提交和回滚 

1.4 事务定义接口 TransactionDefinition

1.4.1 事务隔离级别 

1.4.2 事务传播行为 

1.4.3 事务超时时限 

2.框架搭建步骤

2.1 项目的大体框架结构 

2.2 使用Navicat创建两个表 

2.3 加入项目需要使用到的Maven依赖(pom.xml

2.4 编写实体类(Goods类、Sale类)

2.4.1 Goods商品实体类 

2.4.2 销售记录实体类 


1.事务的概念


什么是事务呢?我们都学过MySQL,那么事务就是一些 sql 序列的集合,由多条 sql 语句构成,作为一个整体执行。

mysql执行事务的代码:👇👇👇 

beginTransaction 开启事务
insert into student(...) values(...)
select * from teacher where id=1001
update school set name=XXX where address=...
endTransaction 结束事务

1.1 Spring中的事务 


事务原本是数据库中的概念,在 Dao 层。但一般情况下,需要将事务提升到业务层,即 Service 层。这样做是为了能够使用事务的特性来管理具体的业务。

Spring 中通常可以通过以下两种方式来实现对事务的管理:
1)使用 Spring 的事务注解管理事务
2)使用 AspectJ AOP 配置管理事务

使用Spring的事务管理器,可以管理不同数据库访问技术的事务处理。开发人员只需要掌握Spring的事务处理方法,就可以实现使用不同的数据库访问技术的事务管理。管理事务面向的是Spring,由Spring来管理事务、做事务提交、事务回滚的操作。


1.2 Spring的事务管理器 

事务管理器是PlatformTransactionManager 接口对象,定义了事物的操作,其主要用于完成事务的提交commit()、回滚rollback(),及获取事务的状态信息。

这个事务管理器接口有很多实现类,一种数据库访问技术对应有一个实现类,由该实现类完成具体的事务提交、回滚。

例如:1JDBCMyBatis的事务管理器的实现类是:DataSourceTransactionManager

          2Hibernate框架的事务管理器的实现类是:HibernateTransactionManager


1.3 关于事务的提交和回滚 


对于这样一个问题:什么时候提交事务?什么时候回滚事务?

当你的业务方法没有异常、正常执行时,事务是提交的。如果你的业务方法抛出了运行时异常,事务是回滚的。

异常的分类:1Error:严重错误,回滚事务。

                     2Exception:异常类,可以打印出来的异常情况。

                          运行时异常:在程序执行过程中抛出的异常,主要是RuntimeException和它的子类。例如:NullPointerExceptionNumberFormatEceptionArithmeticExceptionIndexOutOfBoundsException

                          受查(编译)异常:编写Java代码的时候,产生的异常,若不处理,则无法通过编译。例如:IOExceptionSQLExceptionFileNotFoundException

总的来说:方法中抛出了运行时异常,则事务回滚;其他情况(正常执行或者是受查异常),则事务提交。


1.4 事务定义接口 TransactionDefinition

事务定义接口 TransactionDefinition 中定义了事务描述相关的三类常量:事务隔离级别、事务传播行为、事务默认超时时限,及对它们的操作。 给业务方法说明事务属性,这个与ACID不一样。

1.4.1 事务隔离级别 

这些常量均是以 ISOLATION_开头。即形如 ISOLATION_XXX

1. DEFAULT DB MySql REPEATABLE_READ Oracle 默认为READ_COMMITTED

2. READ_UNCOMMITTED:读未提交。未解决任何并发问题。

3. READ_COMMITTED:读已提交。解决脏读,存在不可重复读与幻读。

4. REPEATABLE_READ:可重复读。解决脏读、不可重复读,存在幻读。

5. SERIALIZABLE:串行化。不存在并发问题。


1.4.2 事务传播行为 

所谓事务传播行为是指,处于不同事务中的方法在相互调用时,执行期间事务的维护情况。如,A 事务中的方法 doSome()调用 B 事务中的方法 doOther(),在调用执行期间事务的维护情况,就称为事务传播行为。事务传播行为是加在方法上的。

事务传播行为常量都是以 PROPAGATION_ 开头,形如 PROPAGATION_XXX

1. PROPAGATION_REQUIRED :指定的方法必须在事务内执行。若当前存在事务,就加入到当前事务中;若当前没有事务,则创建一个新事务。这种传播行为是最常见的选择,也是Spring 默认的事务传播行为。

2. PROPAGATION_REQUIRES_NEW :指定的方法支持当前事务,但若当前没有事务,也可以以非事务方式执行。

3. PROPAGATION_SUPPORTS :总是新建一个事务,若当前存在事务,就将当前事务挂起,直到新事务执行完毕。

4. PROPAGATION_MANDATORY

5. PROPAGATION_NESTED

6. PROPAGATION_NEVER

7. PROPAGATION_NOT_SUPPORTED


1.4.3 事务超时时限 

常量 TIMEOUT_DEFAULT 定义了事务底层默认的超时时限,sql 语句的执行时长。注意,事务的超时时限起作用的条件比较多,且超时的时间计算点较复杂。所以,该值一般就使用默认值即可。 

超时时限以秒为单位,是一个整数值,默认值为 -1

2.框架搭建步骤


2.1 项目的大体框架结构 

2.2 使用Navicat创建两个表 

其中 sale 表存放的是销售记录,id表示销售记录的编号,主键,是自动增长的;gid是购买的商品编号;num是购买的商品数量。初始情况下,sale表中无数据。 

goods表存放是每种商品的具体信息。id是商品编号,主键;name是商品名称;amount是商品库存;price是商品单价。

初始情况下,向goods表中添加两条数据,如下:👇👇👇

2.3 加入项目需要使用到的Maven依赖(pom.xml

<dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    <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>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.1</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.1</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.9</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.12</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <resources>
      <resource>
        <directory>src/main/java</directory><!--所在的目录-->
        <includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
  </build>

2.4 编写实体类Goods类、Sale类)


2.4.1 Goods商品实体类 

package com.bjpowernode.entity;
/**
 *
 */
public class Goods {
    //商品编号,主键
    private Integer id;
    //商品名称
    private String name;
    //商品库存
    private  Integer amount;
    //商品单价
    private Float price;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAmount() {
        return amount;
    }
    public void setAmount(Integer amount) {
        this.amount = amount;
    }
    public Float getPrice() {
        return price;
    }
    public void setPrice(Float price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "Goods{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", amount=" + amount +
                ", price=" + price +
                '}';
    }
}

2.4.2 销售记录实体类 

package com.bjpowernode.entity;
/**
 *
 */
public class Sale {
    //主键
    private Integer id;
    //购买商品的id
    private Integer gid;
    //购买商品的数量
    private Integer num;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Integer getGid() {
        return gid;
    }
    public void setGid(Integer gid) {
        this.gid = gid;
    }
    public Integer getNum() {
        return num;
    }
    public void setNum(Integer num) {
        this.num = num;
    }
    @Override
    public String toString() {
        return "Sale{" +
                "id=" + id +
                ", gid=" + gid +
                ", num=" + num +
                '}';
    }
}
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
17天前
|
Java Spring
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
150 73
|
12天前
|
Java Spring 容器
【SpringFramework】Spring IoC-基于注解的实现
本文主要记录基于Spring注解实现IoC容器和DI相关知识。
45 21
|
18天前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
6天前
|
SQL Java 关系型数据库
【SpringFramework】Spring事务
本文简述Spring中数据库及事务相关衍伸知识点。
35 9
|
13天前
|
Java 开发者 Spring
理解和解决Spring框架中的事务自调用问题
事务自调用问题是由于 Spring AOP 代理机制引起的,当方法在同一个类内部自调用时,事务注解将失效。通过使用代理对象调用、将事务逻辑分离到不同类中或使用 AspectJ 模式,可以有效解决这一问题。理解和解决这一问题,对于保证 Spring 应用中的事务管理正确性至关重要。掌握这些技巧,可以提高开发效率和代码的健壮性。
43 13
|
17天前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
17天前
|
Java Spring
【Spring配置】idea编码格式导致注解汉字无法保存
问题一:对于同一个项目,我们在使用idea的过程中,使用汉字注解完后,再打开该项目,汉字变成乱码问题二:本来a项目中,汉字注解调试好了,没有乱码了,但是创建出来的新的项目,写的注解又成乱码了。
|
3月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
275 2
|
4天前
|
Java 测试技术 应用服务中间件
Spring Boot 如何测试打包部署
本文介绍了 Spring Boot 项目的开发、调试、打包及投产上线的全流程。主要内容包括: 1. **单元测试**:通过添加 `spring-boot-starter-test` 包,使用 `@RunWith(SpringRunner.class)` 和 `@SpringBootTest` 注解进行测试类开发。 2. **集成测试**:支持热部署,通过添加 `spring-boot-devtools` 实现代码修改后自动重启。 3. **投产上线**:提供两种部署方案,一是打包成 jar 包直接运行,二是打包成 war 包部署到 Tomcat 服务器。
25 10
|
18天前
|
Java 数据库连接 Maven
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
自动装配是现在面试中常考的一道面试题。本文基于最新的 SpringBoot 3.3.3 版本的源码来分析自动装配的原理,并在文未说明了SpringBoot2和SpringBoot3的自动装配源码中区别,以及面试回答的拿分核心话术。
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)