首页 > 其他分享 >Spring全家桶(四):Spring 事务

Spring全家桶(四):Spring 事务

时间:2024-08-10 13:27:16浏览次数:15  
标签:事务 管理器 Spring Transactional 全家 spring 注解

Spring 声明式事务

1. 声明式事务概念

什么是事务
  • 事务作用:在数据层保障一系列的数据库操作同成功同失败
  • Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败
1.1 编程式事务

编程式事务是指手动编写程序来管理事务,即通过编写代码的方式直接控制事务的提交和回滚。在 Java 中,通常使用事务管理器(如 Spring 中的 PlatformTransactionManager)来实现编程式事务。

编程式事务的主要优点是灵活性高,可以按照自己的需求来控制事务的粒度、模式等等。但是,编写大量的事务控制代码容易出现问题,对代码的可读性和可维护性有一定影响。

Connection conn = ...;
  
try {
    // 开启事务:关闭事务的自动提交
    conn.setAutoCommit(false);
    // 核心操作
    // 业务代码
    // 提交事务
    conn.commit();
  
}catch(Exception e){
  
    // 回滚事务
    conn.rollBack();
  
}finally{
  
    // 释放数据库连接
    conn.close();
  
}

编程式的实现方式存在缺陷:

  • 细节没有被屏蔽:具体操作过程中,所有细节都需要程序员自己来完成,比较繁琐。

  • 代码复用性不高:如果没有有效抽取出来,每次实现功能都需要自己编写代码,代码就没有得到复用。 

1.2 声明式事务

声明式事务是指使用注解或 XML 配置的方式来控制事务的提交和回滚。

开发者只需要添加配置即可, 具体事务的实现由第三方框架实现,避免我们直接进行事务操作!

使用声明式事务可以将事务的控制和业务逻辑分离开来,提高代码的可读性和可维护性。

区别:

  • 编程式事务需要手动编写代码来管理事务

  • 而声明式事务可以通过配置文件或注解来控制事务。

1.3 Spring事务管理器
  1. Spring声明式事务对应依赖

    • spring-tx: 包含声明式事务实现的基本规范(事务管理器规范接口和事务增强等等)

    • spring-jdbc: 包含DataSource方式事务管理器实现类DataSourceTransactionManager

    • spring-orm: 包含其他持久层框架的事务管理器实现类例如:Hibernate/Jpa等

  2. Spring声明式事务对应事务管理器接口

 

我们现在要使用的事务管理器是org.springframework.jdbc.datasource.DataSourceTransactionManager,将来整合 JDBC方式、JdbcTemplate方式、Mybatis方式的事务实现!

DataSourceTransactionManager类中的主要方法:

  • doBegin():开启事务

  • doSuspend():挂起事务

  • doResume():恢复挂起的事务

  • doCommit():提交事务

  • doRollback():回滚事务

2. 基于注解的声明式事务

2.1 事务属性:只读

1.只读介绍

对一个查询操作来说,如果我们把它设置成只读,就能够明确告诉数据库,这个操作不涉及写操作。这样数据库就能够针对查询操作来进行优化。

2.设置方式

// readOnly = true把当前事务设置为只读 默认是false!
@Transactional(readOnly = true)

3.针对DML动作设置只读模式

会抛出下面异常:

Caused by: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed

4.@Transactional注解放在类上

  1. 生效原则

    如果一个类中每一个方法上都使用了 @Transactional 注解,那么就可以将 @Transactional 注解提取到类上。反过来说:@Transactional 注解在类级别标记,会影响到类中的每一个方法。同时,类级别标记的 @Transactional 注解中设置的事务属性也会延续影响到方法执行时的事务属性。除非在方法上又设置了 @Transactional 注解。

    对一个方法来说,离它最近的 @Transactional 注解中的事务属性设置生效。

  2. 用法举例

    在类级别@Transactional注解中设置只读,这样类中所有的查询方法都不需要设置@Transactional注解了。因为对查询操作来说,其他属性通常不需要设置,所以使用公共设置即可。

    然后在这个基础上,对增删改方法设置@Transactional注解 readOnly 属性为 false。

@Service
@Transactional(readOnly = true)
public class EmpService {
    
    // 为了便于核对数据库操作结果,不要修改同一条记录
    @Transactional(readOnly = false)
    public void updateTwice(……) {
    ……
    }
    
    // readOnly = true把当前事务设置为只读
    // @Transactional(readOnly = true)
    public String getEmpName(Integer empId) {
    ……
    }
    
}
 2.2 事务属性:超时时间

1.需求

事务在执行过程中,有可能因为遇到某些问题,导致程序卡住,从而长时间占用数据库资源。而长时间占用资源,大概率是因为程序运行出现了问题(可能是Java程序或MySQL数据库或网络连接等等)。

此时这个很可能出问题的程序应该被回滚,撤销它已做的操作,事务结束,把资源让出来,让其他正常程序可以执行。

概括来说就是一句话:超时回滚,释放资源。

2.设置超时时间

@Service
public class StudentService {

    @Autowired
    private StudentDao studentDao;

    /**
     * timeout设置事务超时时间,单位秒! 默认: -1 永不超时,不限制事务时间!
     */
    @Transactional(readOnly = false,timeout = 3)
    public void changeInfo(){
        studentDao.updateAgeById(100,1);
        //休眠4秒,等待方法超时!
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        studentDao.updateNameById("test1",1);
    }
}

 3.测试超时效果

执行抛出事务超时异常

org.springframework.transaction.TransactionTimedOutException: Transaction timed out: deadline was Wed May 24 09:10:43 IRKT 2023

  at org.springframework.transaction.support.ResourceHolderSupport.checkTransactionTimeout(ResourceHolderSupport.java:155)
  at org.springframework.transaction.support.ResourceHolderSupport.getTimeToLiveInMillis(ResourceHolderSupport.java:144)
  at org.springframework.transaction.support.ResourceHolderSupport.getTimeToLiveInSeconds(ResourceHolderSupport.java:128)
  at org.springframework.jdbc.datasource.DataSourceUtils.applyTimeout(DataSourceUtils.java:341)
  at org.springframework.jdbc.core.JdbcTemplate.applyStatementSettings(JdbcTemplate.java:1467)
2.3 事务属性:事务隔离级别
  1. 事务隔离级别

    数据库事务的隔离级别是指在多个事务并发执行时,数据库系统为了保证数据一致性所遵循的规定。常见的隔离级别包括:

    1. 读未提交(Read Uncommitted):事务可以读取未被提交的数据,容易产生脏读、不可重复读和幻读等问题。实现简单但不太安全,一般不用。

    2. 读已提交(Read Committed):事务只能读取已经提交的数据,可以避免脏读问题,但可能引发不可重复读和幻读。

    3. 可重复读(Repeatable Read):在一个事务中,相同的查询将返回相同的结果集,不管其他事务对数据做了什么修改。可以避免脏读和不可重复读,但仍有幻读的问题。

    4. 串行化(Serializable):最高的隔离级别,完全禁止了并发,只允许一个事务执行完毕之后才能执行另一个事务。可以避免以上所有问题,但效率较低,不适用于高并发场景。 不同的隔离级别适用于不同的场景,需要根据实际业务需求进行选择和调整。

2.4 事务属性:事务传播行为

 

2.5事务配置 

 3.Spring核心掌握总结

核心点掌握目标
spring框架理解spring家族和spring framework框架
spring核心功能ioc/di , aop , tx
spring ioc / di组件管理、ioc容器、ioc/di , 三种配置方式
spring aopaop和aop框架和代理技术、基于注解的aop配置
spring tx声明式和编程式事务、动态事务管理器、事务注解、属性

标签:事务,管理器,Spring,Transactional,全家,spring,注解
From: https://blog.csdn.net/c55555556/article/details/140995704

相关文章

  • 基于SpringBoot+Vue的互联网违法行为举报平台设计和实现(源码+论文+部署讲解等)
    博主介绍:✌全网粉丝50W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、P......
  • 基于SpringBoot的疗养院管理系统源码数据库
    摘 要传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装疗养院管理系统软件来发挥其高效地信息处理的作用,可以规范信息管理流程,让管理工作可以系统化和程序化,同时,疗养院管理系统的......
  • Spring源码系列六:AOP
    更多请关注:https://t.zsxq.com/fhroW文章目录ProxyFactory使用ProxyFactoryAdviceThrowsAdviceMethodInterceptorAdvisor通过spring产生代理对象TargetSourceSpringAop创建流程判断ProxyFactory使用JDK代理还是CGLIB代理拓展ProxyFactoryProxyFactory是Sprin......
  • Spring源码系列五:循环依赖
    更多请关注:https://t.zsxq.com/fhroW文章目录什么是循环依赖?解决思想spring如何解决循环依赖三级缓存补充什么是循环依赖?循环依赖是spring中的问题,普通的java项目不会有循环依赖。Spring中出现的循环依赖有三种情况:自我依赖、循环依赖、多组依赖什么是循环......
  • 【Java毕设选题推荐】基于SpringBoot的springbootJAVA的邮件过滤系统设计与实现
    前言:我是IT源码社,从事计算机开发行业数年,专注Java领域,专业提供程序设计开发、源码分享、技术指导讲解、定制和毕业设计服务......
  • 【Java毕设选题推荐】基于SpringBoot的O2O生鲜食品订购小程序
    前言:我是IT源码社,从事计算机开发行业数年,专注Java领域,专业提供程序设计开发、源码分享、技术指导讲解、定制和毕业设计服务......
  • Spring Boot集成Redis
    目录1.Redis简介2.添加依赖3.项目配置4.使用RedisStringTestSetTestListTestHashTestZSetTest5.测试结果1.Redis简介Redis是一款基于内存的使用K-V结构存取数据的NoSQL非关系型数据库。Redis的主要作用就是缓存数据,通常,会将关系型数据库(例如MySQL等)中的数据读......
  • 毕业设计:基于Springboot的口腔医院微信小程序【代码+论文+PPT】
    全文内容包括:1、采用技术;2、系统功能;3、系统截图;4、配套内容。索取方式见文末微信号,欢迎关注收藏!一、采用技术语言:Java1.8框架:SpringBoot数据库:MySQL5.7、8.0开发工具:IntelliJIDEA旗舰版、微信开发工具其他:Maven3.8以上二、系统功能系统首页:展示口腔医院微信小程序的主......
  • Springboot+Mybatis实现最简单的增删改查
    1.创建一个SpringBoot项目 2.导入依赖勾选上web下面的SpringWeb和sql下面的MySQL和Mybatis依赖 然后等待依赖下载导入2.1 依赖导入后的页面3.创建需要的包和Mybatis配置文件 3.1在原来的com.mybatis包下创建了entity,controller,service,mapper四个包3.2在resource......
  • Spring AI 更新:支持OpenAI的结构化输出,增强对JSON响应的支持
    就在昨晚,SpringAI发了个比较重要的更新。由于最近OpenAI推出了结构化输出的功能,可确保AI生成的响应严格遵守预定义的JSON模式。此功能显着提高了人工智能生成内容在现实应用中的可靠性和可用性。SpringAI紧随其后,现在也可以对OpenAI的结构化输出完美支持了。下图展示了本......