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

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS AI 助手,专业版
简介: 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 +
                '}';
    }
}
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
5月前
|
缓存 监控 Java
SpringBoot @Scheduled 注解详解
使用`@Scheduled`注解实现方法周期性执行,支持固定间隔、延迟或Cron表达式触发,基于Spring Task,适用于日志清理、数据同步等定时任务场景。需启用`@EnableScheduling`,注意线程阻塞与分布式重复问题,推荐结合`@Async`异步处理,提升任务调度效率。
877 128
|
5月前
|
SQL Java 关系型数据库
Spring事务传播机制:7种姿势教你玩转"事务接力赛"
事务传播机制是Spring框架中用于管理事务行为的重要概念,它决定了在方法调用时事务如何传递与执行。通过7种传播行为,开发者可以灵活控制事务边界,适应不同业务场景。例如:REQUIRED默认加入或新建事务,REQUIRES_NEW独立开启新事务,NESTED支持嵌套回滚等。合理使用传播机制不仅能保障数据一致性,还能提升系统性能与健壮性。掌握这“七种人格”,才能在复杂业务中游刃有余。
|
4月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
568 2
|
5月前
|
XML Java 数据格式
常用SpringBoot注解汇总与用法说明
这些注解的使用和组合是Spring Boot快速开发和微服务实现的基础,通过它们,可以有效地指导Spring容器进行类发现、自动装配、配置、代理和管理等核心功能。开发者应当根据项目实际需求,运用这些注解来优化代码结构和服务逻辑。
426 12
|
5月前
|
传感器 Java 数据库
探索Spring Boot的@Conditional注解的上下文配置
Spring Boot 的 `@Conditional` 注解可根据不同条件动态控制 Bean 的加载,提升应用的灵活性与可配置性。本文深入解析其用法与优势,并结合实例展示如何通过自定义条件类实现环境适配的智能配置。
308 0
探索Spring Boot的@Conditional注解的上下文配置
|
5月前
|
智能设计 Java 测试技术
Spring中最大化@Lazy注解,实现资源高效利用
本文深入探讨了 Spring 框架中的 `@Lazy` 注解,介绍了其在资源管理和性能优化中的作用。通过延迟初始化 Bean,`@Lazy` 可显著提升应用启动速度,合理利用系统资源,并增强对 Bean 生命周期的控制。文章还分析了 `@Lazy` 的工作机制、使用场景、最佳实践以及常见陷阱与解决方案,帮助开发者更高效地构建可扩展、高性能的 Spring 应用程序。
238 0
Spring中最大化@Lazy注解,实现资源高效利用
|
监控 Java 数据库
Spring事务相关配置、案例:转账业务追加日志及事务传播行为
Spring事务相关配置、案例:转账业务追加日志及事务传播行为
238 0
|
存储 Java 数据库
Spring事务和事务传播机制
Spring事务和事务传播机制
232 0
|
Java 开发者 Spring
Spring高手之路24——事务类型及传播行为实战指南
本篇文章深入探讨了Spring中的事务管理,特别是事务传播行为(如REQUIRES_NEW和NESTED)的应用与区别。通过详实的示例和优化的时序图,全面解析如何在实际项目中使用这些高级事务控制技巧,以提升开发者的Spring事务管理能力。
388 1
Spring高手之路24——事务类型及传播行为实战指南
|
Java 关系型数据库 数据库
京东面试:聊聊Spring事务?Spring事务的10种失效场景?加入型传播和嵌套型传播有什么区别?
45岁老架构师尼恩分享了Spring事务的核心知识点,包括事务的两种管理方式(编程式和声明式)、@Transactional注解的五大属性(transactionManager、propagation、isolation、timeout、readOnly、rollbackFor)、事务的七种传播行为、事务隔离级别及其与数据库隔离级别的关系,以及Spring事务的10种失效场景。尼恩还强调了面试中如何给出高质量答案,推荐阅读《尼恩Java面试宝典PDF》以提升面试表现。更多技术资料可在公众号【技术自由圈】获取。