Spring框架的事务处理-spring框架入门到精通

简介: 事务是逻辑上的一组操作,要么都执行,要么都不执行。我们系统的每个业务方法可能包括了多个原子性的数据库操作,比如下面的 savePerson() 方法中就有两个原子性的数据库操作。这些原子性的数据库操作是有依赖的,它们要么都执行,要不就都不执行。

1.什么是事务

事务是逻辑上的一组操作,要么都执行,要么都不执行。

我们系统的每个业务方法可能包括了多个原子性的数据库操作,比如下面的 savePerson() 方法中就有两个原子性的数据库操作。这些原子性的数据库操作是有依赖的,它们要么都执行,要不就都不执行。

搭配视频教程学习:https://www.bilibili.com/video/BV1nz4y1d7uy

public void savePerson() { 
 personDao.save(person);
 personDetailDao.save(personDetail);
 }

另外,需要格外注意的是:事务能否生效数据库引擎是否支持事务是关键。比如常用的 MySQL 数据库默认使用支持事务的innodb引擎。但是,如果把数据库引擎变为 myisam,那么程序也就不再支持事务了!

2.在什么时候想到使用事务

当我们的操作涉及到多个表,或者是多个sql语句的增加insert删除delete修改update的时候,需要保证这些语句都是成功才能完成我们的功能;或者保证这些语句都失败,保证操作是符合要求的。最明了的例子就是转账,从A账户转到B账户中,要保证从A中扣除的金额一定要加到B里去。如果A到B转账成功,那么A扣B加,要保证A和B的账户是均衡的。如果A向B转账的过程中扣款失败了,那就应该把操作都回退,A也不扣,B也不加,保证A和B中账户数据的平衡。

在java代码中写程序,控制事务,此时事务应该放在哪里呢?

在开发中,事务是放在serviceImpl类的业务方法上的,因为一个业务方法可能涉及到多个dao的调用,执行多个sql语句。

3.使用JDBC访问数据库,还是Mybatis访问数据库怎么处理事务

JDBC访问数据库,处理事务:连接对象Connection conn;事务提交 conn.commit ();事务回滚:conn.rollback ();

Mybatis 访问数据库,处理事务:事务提交:SqlSession.commit ();事务回滚:SqlSession.rollback ();

4. 问题3中事务的处理方式有什么不足

(1)不同的数据库访问技术,处理事务的对象,方法不同。JDBC使用的是Connection对象,Mybatis访问对象使用的事SqlSession。方法不同就需要了解不同数据库访问技术使用事务的原理。

(2)掌握多种数据库中事务的处理逻辑,知道什么时候提交,什么时候回滚。

(3)处理事务的多种方法。

总结:多种数据库的访问技术,有不同的事务处理的机制,对象,方法。

5.怎么解决问题4中的这些不足

spring提供了一种处理事务的统一模型,能使用统一的步骤,方式,完成多种不同数据库访问技术的事务处理。

使用spring的事务处理机制,可以完成MyBatis访问数据库的事务处理。

使用spring的事务处理机制,可以完成Hibernate访问数据库的事务处理
image.png

6.处理事务需要怎么做,做什么

Spring处理事务的模型,使用的步骤都是固定的。我们只需要把事务使用的信息提供给spring就可以了。

(1) 事务内部提交,回滚事务,使用的是事务管理器对象,代替我们完成事务的提交commit()和回滚rollback ()操作。事务管理器是一个接口和他的众多实现类。事务管理器是PlatformTransactionManager接口对象,接口中定义了事务的重要方法:一个是提交commit(),一个是回滚rollback();

这个接口的实现类有很多:spirng把每一种数据库访问技术对应的事务处理类都创建好了。

如果我们使用的是MyBatis访问数据库,那Spring创建好的是DataSourceTansactionManager;

如果我们使用的是Hibernate访问数据库,那Spring创建好的是HibernateTansactionManager。

那我们怎么去用Spring创建好的这些事务处理类呢?

我们需要告诉Spring我们使用的是那种数据库访问技术。

怎么告诉Spring呢?

需要声明数据库访问技术对应的事务管理器的实现类,在spring的配置文件中使用声明就可以了,声明之后spring就知道我们用的是那种数据库访问技术了。

例如,我们要使用MyBatis访问数据库,我们就应该在xml配置文件中声明一个DataSourceTansactionManager的bean对象;

(2)我们的业务方法需要什么样的事务呢?需要提供一下事务的类型。

  • 说明方法需要的事务:

事务的隔离级别:有4个值。在TransactionDefinition中定义了事务描述相关的3类常量:分别是事务隔离级别、事务传播行为以及事务默认超时时限。在事务隔离级别中定义了5个事务隔离级别的常量,这些常量都以ISOLATION_开头,形如ISOLATION_xxx 。

default:采用数据库默认的隔离级别。MySql的默认隔离级别为可重复读(repeatable_read ),Oracle 默认为读已提交(read_commit )。

另外的4个真正有效值:

  1. read _uncommitted:读未提交。未解决任何并发问题。
  2. read _commited:读已提交。解决脏读,存在不可重复读和幻读。
  3. repeatable_read:可重复读。解决脏读和不可重复读,存在幻读。
  4. serializable:串行化,不存在并发问题。
  • 事务的超时时间(timeout),表示一个方法最长的执行时间,如果方法执行时超过了这个时间,事务就回滚。超时时间的单位是s,默认是-1,代表没有超时时间。

事务的传播行为:控制业务方法是不是有事务的,是什么样的事务的。

  • 事务的传播行为一共有7个(propagation_xxx):表示我们的业务方法在调用时,事务在方法之间是如何使用的。通过传播行为,我们能控制这个方法到底有没有事务,有什么样的事务。

propagation _required :指定的方法必须有事务。若存在事务,就加入到当前事务中,若没有事务就创建一个新事务。是spring中最常见的事务传播行为,也是默认的事务传播行为。

举例:

如果传播行为加在doOther()方法上。doSome()方法内调用doOther()方法。如果doSome()方法在调用doOther()方法时就是在事务内运行的,那么doOther()方法的执行也加入到已存在的该事务内执行。如果doSome()方法在调用doOther()方法时没有在事务内执行,那么doOther()方法会自己创建一个事务,并在这个新创建的事务中执行。

propagation _requires new :新事务。方法在执行时一定是新建一个事务,不用别人提供的事务。如果当前已经存在事务,就将当前事务挂起,知道新事务执行完毕。

propagation _supports :指定的方法支持当前事务,但是如果当前没有事务,也可以执行。就是说,有事务也可以,没事务也行。

propagation_mandatory 、propagation _nested 、propagation _never 、propagation _not _supported 。

(3)提交事务、回滚事务的时机

  • 当业务方法执行成功,没有异常抛出,当方法执行完毕,Spring在方法执行后提交事务。事务管理器commit
  • 当你的业务方法抛出运行时异常或者error,Spring执行回滚,调用事务管理器的rollback运行时异常的定义:RuntimeException和他的子类都是运行时异常,例如NullPointException、NumberFormatException
  • 当你的业务方法抛出非运行时异常,主要是受查异常时,提交事务。受查异常的定义:在你写代码时,必须处理的异常,例如IOException和SQLException。

总结Spring的事务:

  1. 管理事务的是事务管理器及其实现类。
  2. Spring的事务是一个统一管理模型:
  • 指定要使用的事务管理器的实现类,使用xml配置文件中的标签
  • 指定哪些类,哪些方法需要加入事务的功能
  • 指定方法需要的隔离级别,传播行为和超时时间

我们需要告诉Spring我们的项目中类信息,方法的名称,方法的事务传播行为。

相关文章
|
7天前
|
缓存 Java 开发工具
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
三级缓存是Spring框架里,一个经典的技术点,它很好地解决了循环依赖的问题,也是很多面试中会被问到的问题,本文从源码入手,详细剖析Spring三级缓存的来龙去脉。
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
|
7天前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
2天前
|
Java 应用服务中间件 开发者
深入探索并实践Spring Boot框架
深入探索并实践Spring Boot框架
13 2
|
2天前
|
机器学习/深度学习 数据采集 JavaScript
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
ADR药品不良反应监测系统是一款智能化工具,用于监测和分析药品不良反应。该系统通过收集和分析病历、处方及实验室数据,快速识别潜在不良反应,提升用药安全性。系统采用Java开发,基于SpringBoot框架,前端使用Vue,具备数据采集、清洗、分析等功能模块,并能生成监测报告辅助医务人员决策。通过集成多种数据源并运用机器学习算法,系统可自动预警药品不良反应,有效减少药害事故,保障公众健康。
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
|
11天前
|
运维 NoSQL Java
SpringBoot接入轻量级分布式日志框架GrayLog技术分享
在当今的软件开发环境中,日志管理扮演着至关重要的角色,尤其是在微服务架构下,分布式日志的统一收集、分析和展示成为了开发者和运维人员必须面对的问题。GrayLog作为一个轻量级的分布式日志框架,以其简洁、高效和易部署的特性,逐渐受到广大开发者的青睐。本文将详细介绍如何在SpringBoot项目中接入GrayLog,以实现日志的集中管理和分析。
50 1
|
15天前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
44 2
|
16天前
|
Cloud Native 安全 Java
Micronaut对决Spring Boot:谁是微服务领域的王者?揭秘两者优劣,选对框架至关重要!
【9月更文挑战第5天】近年来,微服务架构备受关注,Micronaut和Spring Boot成为热门选择。Micronaut由OCI开发,基于注解的依赖注入,内置多种特性,轻量级且启动迅速;Spring Boot则简化了Spring应用开发,拥有丰富的生态支持。选择框架需考虑项目需求、团队经验、性能要求及社区支持等因素。希望本文能帮助您选择合适的微服务框架,助力您的软件开发项目取得成功!
64 2
|
17天前
|
JavaScript 前端开发 Java
【颠覆传统】Spring框架如何用WebSocket技术重塑实时通信格局?揭秘背后的故事与技术细节!
【9月更文挑战第4天】随着Web应用对实时交互需求的增长,传统的HTTP模型已无法满足现代应用的要求,特别是在需要持续、双向通信的场景下。WebSocket协议由此诞生,提供全双工通信渠道,使服务器与客户端能实时互发消息。作为Java开发中最受欢迎的框架之一,Spring通过其WebSocket模块支持这一协议,简化了WebSocket在Spring应用中的集成。
35 0
|
20天前
|
Java Spring 容器
彻底改变你的编程人生!揭秘 Spring 框架依赖注入的神奇魔力,让你的代码瞬间焕然一新!
【8月更文挑战第31天】本文介绍 Spring 框架中的依赖注入(DI),一种降低代码耦合度的设计模式。通过 Spring 的 DI 容器,开发者可专注业务逻辑而非依赖管理。文中详细解释了 DI 的基本概念及其实现方式,如构造器注入、字段注入与 setter 方法注入,并提供示例说明如何在实际项目中应用这些技术。通过 Spring 的 @Configuration 和 @Bean 注解,可轻松定义与管理应用中的组件及其依赖关系,实现更简洁、易维护的代码结构。
26 0
|
20天前
|
消息中间件 Kafka Java
Spring 框架与 Kafka 联姻,竟引发软件世界的革命风暴!事件驱动架构震撼登场!
【8月更文挑战第31天】《Spring 框架与 Kafka 集成:实现事件驱动架构》介绍如何利用 Spring 框架的强大功能与 Kafka 分布式流平台结合,构建灵活且可扩展的事件驱动系统。通过添加 Spring Kafka 依赖并配置 Kafka 连接信息,可以轻松实现消息的生产和消费。文中详细展示了如何设置 `KafkaTemplate`、`ProducerFactory` 和 `ConsumerFactory`,并通过示例代码说明了生产者发送消息及消费者接收消息的具体实现。这一组合为构建高效可靠的分布式应用程序提供了有力支持。
58 0