Spring中事务的详细介绍,附带代码示例

文章目录

  • 1、事务的四大特性
  • 2、Spring事务的实现方式
  • 3、数据库怎么处理事务
    • 4、处理事务的方式
    • 4、事务的隔离级别
    • 5、事务的超时时间
    • 6、事务的传播行为
    • 7、Spring事务处理方案
      • 1、中小项目使用
      • 2、大型项目使用AspectJ框架
  • 4、Spring项目实现事务示例
  • 5、SpringBoot项目实现事务示例

在Spring中,事务是一系列的数据操作,要么全部执行完成,要么都不执行。这确保了数据的一致性和完整性。

1、事务的四大特性

事务的主要特性包括 原子性、一致性、隔离性和持久性。

  • 原子性 指的是事务是一个原子操作,由一系列动作组成,这些动作要么全部完成,要么完全不起作用。
  • 一致性 确保一旦事务完成(无论成功还是失败),系统必须处于一致的状态。
  • 隔离性 指的是事务之间应该隔离开来,因为可能有许多事务会同时处理相同的数据,每个事务都应该与其他事务有隔离策略。
  • 持久性 则表示一旦事务完成,其结果将不会受到影响,通常会被写到持久化存储器中。

2、Spring事务的实现方式

在Spring中,事务管理可以通过 编程式事务管理声明式事务管理 两种方式实现。

  • 编程式事务管理需要显式执行事务,如使用TransactionTemplate,需要显式调用commit或rollback方法。
  • 而声明式事务管理建立在AOP(面向切面编程)之上,通过AOP功能对方法前后进行拦截,将事务处理的功能编织到拦截的方法中。这种方式无需在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明或通过注解(如@Transactional)来管理事务。

当我的操作,涉及得到多个表,或者是多个sql语句的insert,update,delete。需要保证这些语句都是成功才能完成我的功能,或者都失败,保证操作是符合要求的。这个时候就需要使用事务。

3、数据库怎么处理事务

  • jdbc访问数据库,处理事务, Connection connconn.commit()conn.rollback()
  • mybatis访问数据库,处理事务, SqlSession.commit()SqlSession.rollback()
  • hibernate访问数据库,处理事务, Session.commit()Session.rollback()

上述事务的处理方式,有什么不足?

  • 不同的数据库访问技术,处理事务的对象,方法不同,需要了解不同数据库访问技术使用事务的原理。
  • 掌握多种数据库中事务的处理逻辑。什么时候提交事务,什么时候回顾事务
  • 处理事务的使用多种方法。

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

怎么解决不足?

  • Spring提供一种处理事务的统一模型,能使用统一步骤,方式完成多种不同数据库访问技术的事务处理。
  • 使用Spring的事务处理机制,可以完成mybatis访问数据库的事务处理。
  • 使用Spring的事务处理机制,可以完成hibernate访问数据库的事务处理。

4、处理事务的方式

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

事务内部提交,回滚事务,使用的事务管理器对象,代替你完成commit,rollback。事务管理器是一个接口和他的众多实现类。

  • 接口:PlatformTransactionManager `,定义了事务重要方法 commit ,rollback。
  • 实现类:Spring把每一种数据库访问技术对应的事务处理类都创建好了。
  • MyBatis访问数据库是 DataSourceTransactionManager
  • Hibernate访问数据库是 HibernateTransactionManager

你需要告诉Spring 你用是那种数据库的访问技术,需要声明数据库访问技术对于的事务管理器实现类, 在Spring的配置文件中使用 <bean> 声明就可以了。

例如,你要使用MyBatis访问数据库,你应该在xml配置文件中配置:

<bean id=“xxx" class="...DataSourceTransactionManager"> 

提交事务和回滚事务的时机:

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

4、事务的隔离级别

你的业务方法需要什么样的事务,说明需要事务的类型。

事务的隔离级别:有4个值,默认为常量值,都是以 ISOLATION 开头的。

  • READ_UNCOMMITTED :读未提交。未解决任何并发问题。
  • READ_COMMITTED :读已提交。解决脏读,存在不可重复读与幻读。
  • REPEATABLE_READ :可重复读。解决脏读、不可重复读,存在幻读。
  • SERIALIZABLE :串行化。不存在并发问题。

DEFAULT :采用 DB 默认的事务隔离级别。MySql 的默认为 REPEATABLE_READ ,Oracle默认为 READ_COMMITTED

5、事务的超时时间

Spring事务的超时时间是指一个事务在执行过程中允许的最长持续时间。如果事务在设定的超时时间内未能完成,则会自动回滚,以确保数据的一致性和完整性。

在Spring中,事务超时时间可以通过以下两种方式进行设置:

  • 使用 @Transactional 注解的 timeout 属性:在需要使用事务的方法上添加 @Transactional 注解,并通过 timeout 属性指定超时时间,单位为秒。例如,@Transactional(timeout = 10) 表示事务超时时间为10秒。
  • 使用编程式事务管理:通过 TransactionTemplate 类手动管理事务,并通过 setTimeout 方法设置超时时间,单位同样为秒。

事务超时时间的设置应根据实际情况进行权衡,过短的超时时间可能导致事务频繁回滚,而过长的超时时间则可能使得系统在等待长时间运行的事务时变得不响应。

需要明确的是,事务超时时间 指的是 数据库执行事务的最长允许时间 ,而不是Java程序执行的时间。因此,在设置事务超时时间时,应考虑到数据库操作的实际情况和性能特点。

6、事务的传播行为

Spring事务传播行为是指当一个事务方法(当前事务)被另一个事务方法(调用者)调用时,这个事务方法(当前事务)对另一个事务方法(调用者)的态度。简单来说,就是当一个事务方法A调用了另一个事务方法B时,B应该如何应对。

Spring框架提供了七种主要的事务传播行为,每种行为都有其特定的用途和适用场景:

  • PROPAGATION_REQUIRED :指定的方法必须在事务内执行。如果当前存在事务,则加入该事务,如果当前没有事务,则创建一个新的事务。这是最常见的选择。
  • PROPAGATION_SUPPORTS :支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务方式执行。
  • PROPAGATION_MANDATORY :支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
  • PROPAGATION_REQUIRES_NEW :创建新事务,无论当前是否存在事务,都创建新事务。
  • PROPAGATION_NOT_SUPPORTED :以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • PROPAGATION_NEVER :以非事务方式执行,如果当前存在事务,则抛出异常。
  • PROPAGATION_NESTED :如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED 类似的操作。

在实际开发中,应根据具体的业务逻辑和事务要求来选择合适的传播行为。同时,还需要注意事务的传播行为与其他事务属性(如隔离级别、只读标志等)的配合使用,以确保事务的正确性和性能。

7、Spring事务处理方案

1、中小项目使用

Spring框架自己用AOP实现给业务方法增加事务的功能, 使用 @Transactional 注解增加事务。

@Transactional 注解是Spring框架自己注解,放在public方法的上面,表示当前方法具有事务。可以给注解的属性赋值,表示具体的隔离级别,传播行为,异常信息等等

使用@Transactional的步骤:

  • 需要声明事务管理器对象
<bean id="xx" class="DataSourceTransactionManager">
  • 开启事务注解驱动, 告诉Spring框架,我要使用注解的方式管理事务。Spring使用AOP机制,创建 @Transactional 所在的类代理对象,给方法加入事务的功能。Spring给业务方法加入事务,在你的业务方法执行之前,先开启事务,在业务方法之后提交或回滚事务,使用AOP的环绕通知。
@Around("你要增加的事务功能的业务方法名称")
public Object myAround(){
// 开启事务,spring给你开启try{buy(1001,10);System.out.println(spring的事务管理器.commit());}catch(Exception e){System.out.println(spring的事务管理器.rollback());}
}

2、大型项目使用AspectJ框架

在Spring配置文件中声明类,方法需要的事务。这种方式业务方法和事务配置完全分离。

实现步骤: 都是在xml配置文件中实现。

  • 要使用的是aspectj框架,需要加入依赖
<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.2.5.RELEASE</version>
</dependency>
  • 声明事务管理器对象
<bean id="xx" class="DataSourceTransactionManager">
  • 声明方法需要的事务类型(配置方法的事务属性【隔离级别,传播行为,超时】)。
  • 配置AOP:指定哪些哪类要创建代理。

4、Spring项目实现事务示例

使用Spring框架进行事务管理通常涉及更多的配置步骤。下面是一个使用 @Transactional 注解的简单示例,演示了如何在 Spring 应用程序中进行事务管理。

首先,假设我们有一个 User 实体类和一个 UserRepository 接口:

@Entity
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;private String email;// getters and setters
}public interface UserRepository extends JpaRepository<User, Long> {// Custom queries can be defined here
}

然后,我们有一个 UserService 类,其中包含一个使用 @Transactional 注解的方法:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class UserService {@Autowiredprivate UserRepository userRepository;@Transactionalpublic User createUser(String name, String email) {User user = new User();user.setName(name);user.setEmail(email);// 假设这里有两个数据库操作,需要确保它们要么都成功,要么都失败userRepository.save(user); // 第一次数据库操作// 模拟一个可能抛出异常的操作if ("invalid-email".equals(email)) {throw new RuntimeException("Invalid email address");}// 第二次数据库操作(这里仅作为示例,实际上可能没有第二次操作)// userRepository.updateSomething(user);return user;}
}

在上面的代码中,createUser 方法被标记为 @Transactional,这意味着该方法内的所有数据库操作都将在一个事务中执行。如果 email"invalid-email",则会抛出一个异常,导致事务回滚,user 不会被保存到数据库中。否则,user 将被成功保存。

注意,默认情况下,@Transactional 注解将事务传播行为设置为 Propagation.REQUIRED,这意味着如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。你还可以根据需要调整事务的传播行为、隔离级别、超时时间等属性。

在实际应用中,@Transactional 注解可以应用于类级别或方法级别,根据具体需求进行配置。同时,还需要确保 Spring 的事务管理器(如 DataSourceTransactionManager)已经配置好,并且相关的数据库连接和 JPA 配置也已经正确设置。

5、SpringBoot项目实现事务示例

以下是一个简单的Spring Boot项目示例,它演示了如何使用@Transactional注解来管理事务。

首先,我们需要一个实体类来表示数据库中的表

import javax.persistence.Entity;  
import javax.persistence.Id;  @Entity  
public class User {  @Id  private Long id;  private String name;  private String email;  // 构造器、getter和setter方法省略  
}

接下来,我们需要一个JPA仓库接口来操作数据库

import org.springframework.data.jpa.repository.JpaRepository;  public interface UserRepository extends JpaRepository<User, Long> {  User findByName(String name);  
}

然后,我们创建一个服务类,该类将使用@Transactional注解来确保事务的完整性

import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Service;  
import org.springframework.transaction.annotation.Transactional;  @Service  
public class UserService {  @Autowired  private UserRepository userRepository;  @Transactional  public User createUser(User user) {  User savedUser = userRepository.save(user);  // 假设这里还有其他数据库操作,比如记录日志等  return savedUser;  }  @Transactional  public void updateUserEmail(Long userId, String newEmail) {  User user = userRepository.findById(userId).orElseThrow(() -> new RuntimeException("User not found"));  user.setEmail(newEmail);  userRepository.save(user);  // 假设这里还有其他数据库操作,比如更新审计记录等  }  
}

在上面的 UserService 类中,createUserupdateUserEmail 方法都被标记为 @Transactional ,这意味着当这些方法被调用时,Spring会创建一个新的事务(如果当前没有事务的话),并在方法执行完毕后提交事务。如果在方法执行期间抛出了任何运行时异常,事务将会被回滚,从而保证了数据的完整性和一致性。

最后,我们需要配置Spring Boot以启用JPA和事务管理

import org.springframework.boot.SpringApplication;  
import org.springframework.boot.autoconfigure.SpringBootApplication;  
import org.springframework.boot.autoconfigure.domain.EntityScan;  
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;  
import org.springframework.context.annotation.EnableTransactionManagement;  
import org.springframework.transaction.annotation.EnableTransactionManagement;  @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})  
@EntityScan("com.example.demo.model") // 替换为你的实体类所在的包路径  
@EnableTransactionManagement  
public class DemoApplication {  public static void main(String[] args) {  SpringApplication.run(DemoApplication.class, args);  }  
}

在这个 DemoApplication 类中,我们使用了 @SpringBootApplication 注解来启用Spring Boot的自动配置功能,并通过 exclude 属性排除了 DataSourceAutoConfiguration ,因为我们可能想要自定义数据源配置。@EntityScan 注解指定了包含实体类的包路径。最后,@EnableTransactionManagement 注解启用了Spring的事务管理功能。

为了运行这个示例,还需要在 application.propertiesapplication.yml 文件中配置数据库连接信息,并添加相应的JPA和数据库驱动依赖到你的 pom.xml 文件中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/823117.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【第3期】PMC对话标杆用户:兆原数通在SeaTunnel的应用实践

&#x1f4e3;随着技术快速发展&#xff0c;企业对数据系统的现代化改造需求日益增加。在这种背景下&#xff0c;如何在保持业务连续性的同时&#xff0c;实现数据系统的平滑迁移与升级呢&#xff1f;加入我们的本期技术访谈节目&#xff0c;来听听李洪军老师分享他们如何利用S…

算法题解记录11+++从前序与中序遍历序列构造二叉树(百日筑基)

题目描述&#xff1a; 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,15,20,7] 输出: [3,…

树莓派驱动开发--iic篇(JY901S陀螺仪的三轴角度简单读取)

前言&#xff1a;既然大家都到了这步&#xff0c;想必对驱动开发有着一定的理解啦吧&#xff01;&#xff01;那我在前面说一下流程&#xff1a; 修改编译设备树》》》编写编译驱动文件》》》编写编译app文件》》》ftp挂载将前面3复制到树莓派的对应位置》》》加载驱动模块》》…

2024软件测试自动化框架都有哪些?

软件行业正迈向自主、快速、高效的未来。为了跟上这个高速前进的生态系统的步伐&#xff0c;必须加快应用程序的交付时间&#xff0c;但不能以牺牲质量为代价。快速实现质量是必要的&#xff0c;因此质量保证得到了很多关注。为了满足卓越的质量和更快的上市时间的需求&#xf…

策略者模式(代码实践C++/Java/Python)————设计模式学习笔记

文章目录 1 设计目标2 Java2.1 涉及知识点2.2 实现2.2.1 实现两个接口飞行为和叫行为2.2.2 实现Duck抽象基类&#xff08;把行为接口作为类成员&#xff09;2.2.3 实现接口飞行为和叫行为的具体行为2.2.4 具体实现鸭子2.2.5 模型调用 3 C&#xff08;用到了大量C2.0的知识&…

数据库SQL语言实战(三)

删除操作 本篇文章重点在于SQL中的各种删除操作 题目一 删除表中的学号不全是数字的那些错误数据&#xff0c;学号应该是数字组成&#xff0c;不能够包含字母空格等非数字字符。方法之一&#xff1a;用substr函数&#xff0c;例如Substr(sid,1,1)返回学号的第一位&#xff0…

C++常考面试题(第二篇)

【题目 16】拷贝构造函数的格式和作用&#xff0c;自动调用拷贝构造函数的几种情形&#xff1f; 格式&#xff1a;没有返回值 函数名和类名相同 参数&#xff1a;const person& 类型引用 作用&#xff1a;逐个给成员变量进行赋值三种情形下会调用拷贝构造函数 (1) 当用一…

Zynq学习笔记--AXI 总线仿真(AXI VIP)

目录 1. 概述 2. Simulation with AXI VIP 2.1 axi_vip_pkg 2.2 design_1_axi_vip_0_0_pkg 2.3 参数指定 3. 实例化注意事项 3.1 名称对应关系 3.2 寄存器地址 3.3 block design 1. 概述 AXI Verification IP&#xff08;AXI VIP&#xff09;是一种用于验证AXI总线协议的…

09 SQL进阶 -- SQL高级处理 -- 窗口函数等

1. 窗口函数 1.1 窗口函数概念及基本的使用方法 窗口函数也称为 OLAP 函数。OLAP 是 OnLine AnalyticalProcessing 的简称,意思是对数据库数据进行实时分析处理。 为了便于理解,称之为窗口函数。常规的 SELECT 语句都是对整张表进行查询,而窗口函数可以让我们有选择的去某…

Spring @Transactional 注解

官方文档&#xff1a;https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/annotations.html#:~:textThe%20%40Transactional%20annotation%20is%20metadata,suspending%20any%20existing%20transaction%22). 推荐阅读&#xff1a;https:…

基于springboot实现大创管理系统【项目源码+论文说明】计算机毕业设计

基于springboot实现大创管理系统演示 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了大创管理系统的开发全过程。通过分析大创管理系统管理的不足&#xff0c;创建了一个计算机管理大创管理系统的方案。文章介…

Re65:读论文 GPT-3 Language Models are Few-Shot Learners

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文全名&#xff1a;Language Models are Few-Shot Learners ArXiv网址&#xff1a;https://arxiv.org/abs/2005.14165 2020 NeurIPS&#xff1a;https://papers.nips.cc/paper/2020/hash/1457c0d6bfcb49674…

集成sa-token实现登录和RBAC权限控制

集成sa-token实现登录和RBAC权限控制 文章目录 1.sa-token是什么&#xff1f;1.1简介1.2官网1.3 Sa-Token 功能一览1.4 功能结构图 2.集成sa-token及配置2.1 pom依赖2.2 yaml配置2.3 代码配置 4.RBAC权限控制表设计5.菜单权限树构造实现5.1菜单权限数据sql查询5.2菜单权限树构建…

solidity(10)

&#x1f52e; Solidity变量指南&#xff1a;探寻状态、局部和全局三界之秘&#x1f30c; 在Solidity的神秘大陆上&#xff0c;变量就像是散落在时间和空间中的宝石&#x1f48e;&#xff0c;每颗都有它独特的魔力和作用域。掌握这三种变量&#xff0c;是成为合约法师的重要一…

Vue项目学习(一)-SQL闯关

Hello , 我是小恒不会java。今天来阅读一个Vue纯前端项目--SQL在线闯关 进步的方法除了文档书籍视频&#xff0c;学会阅读源代码&#xff0c;从代码中学会解决需求的方法也是必要的 已部署完成&#xff0c;在线体验&#xff1a;http://sql.yunduanjianzhan.cn 背景 简介 闯…

《黑神话:悟空》现已正式上架PS商城,今晚或有大动作

关于《黑神话&#xff1a;悟空》的消息可谓是喜闻乐见&#xff01;今天晚上19:10可能会有相关游戏内容放出&#xff0c;让人非常期待。而海信电视推出的《黑神话&#xff1a;悟空》专属画质模式&#xff0c;让玩家可以享受到更加细腻的游戏画面。 此外&#xff0c;海信和《黑神…

高级感拉满的个人UI网页

效果图 PC端 移动端 部分代码 index.html <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>Zboy的主页</title><link rel"stylesheet" href"css/normalize.css" /><link rel&qu…

SAP项目任务一览表

根据SAP Activate项目管理方法论的主要精神&#xff0c;浓缩到一些主要的团队和任务。 主要的团队有&#xff1a; 项目管理(办公室)Project Management(office)&#xff1a;项目经理团队&#xff0c;包括项目办公室。负责项目整体运行和监控&#xff0c;项目办公室负责项目的…

李沐-19 卷积层【动手学深度学习v2】

记录下关于权重下标变换的理解&#xff1a; 从原来的Wi,j到Wi,j,k,l是从二维到四维的过程&#xff0c;如下图所示 对全连接层使用平移不变性(如&#xff1a;卷积核在移动过程是不变的)和局部性&#xff08;如&#xff1a;卷积核有一定大小&#xff09;得到卷积层&#xff0c;这…

【leetcode】双指针算法技巧——滑动窗口

标题&#xff1a;【leetcode】双指针算法技巧——滑动窗口 水墨不写bug 正文开始&#xff1a; 滑动窗口介绍 滑动窗口是一种常用的算法技巧&#xff0c;用于解决一些涉及 连续子数组或子串 的问题。它的基本思想是 维护一个窗口&#xff0c;通过 在窗口内移动 来寻找满…