spring事务处理

spring事务

事务介绍

一个事务要么同时成功,要么同时失败

特性
  • Atomic原子性 事务是由一个或多个活动组成的一个工作单元。原子性确保事务中的所有操作全部发生或全部不发生

  • Consistent一致性 一旦事务完成,系统必须确保它所建模的业务处于一致的状态

  • Isolated隔离性 事务允许多个用户对数据进行操作,每个用户的操作不会与其他用户纠缠在一起,多个事务之间数据要相互隔离

  • Durable持久性 一旦事务完成,事务的结果应该持久化

事务隔离级别
  • DEFAULT 使用底层数据库预设的隔离层级
  • READ_UNCOMMITTED (读未提交的数据) 允许事务读取其他并行的事务还没提交的数据,脏读、不可重复读、幻读问题都存在
  • READ_COMMITTED(读已提交的数据) 只允许事务读取其他并行事务提交的数据,可以避免脏读,但是不可重复读和幻读仍存在
  • REPEATABLE_READ(可重复读) 确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新,可以避免脏读和不可重复读,但幻读仍存在(Mysql默认的事务隔离级别)
  • SERIALIZABLE(串行化) 确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,所有并发问题都可以避免,但是性能低下

脏读: 一个未提交事务读取到另一个未提交事务的数据,读得数据已经被修改了,已经过时失去意义了

不可重复读: 一个未提交事务读取到另一个提交事务修改的数据,同一个事务里面多次读取同一行数据,却返回不同的结果

幻读:一个未提交事务读取到另一个提交事务添加的数据,同样一个查询在整个事务过程中多次执行后,查询所得的结果集不一样

传播行为
  • PROPAGATION_REQUIRED 支持当前事务,如果当前没有事务,就新建一个事务;如果有事务,就在这个事务内运行

  • PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行;如果有事务,就在这个事务内运行

  • PROPAGATION_MANDATORY 支持当前事务,如果当前没有事务,就抛出异常。配置该传播级别是有效的控制上下文调用代码遗漏添加事务控制的保证手段。

  • PROPAGATION_REQUIRED_NEW 新建事务,如果当前存在事务,把当前事务挂起

  • PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。可以缩小事务

  • PROPAGATION_NEVER 以非事务方式执行操作,如果当前存在事务,则抛出异常

  • PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行,被嵌套的事务可从当前事务中单独地提交或回滚;如果当前没有事务,则新建事务

只读

事务只进行读取操作

readOnly=true 告诉spring当前事务只会进行读取操作,不会进行修改操作,可以帮助数据库引擎优化

注:如果设置为只读的话,千万不要在事务里修改数据,使用只读操作时,spring不会进行加锁处理,如果修改数据的话,会出现问题

事务超时

事务时间过长,则回滚,默认是-1

回滚规则

默认是发生运行时异常回滚

rollback-for 指事务对于哪些异常应当回滚而不提交(默认spring会对所有的运行时异常回滚)

no-rollback-for 指事务对于哪些异常继续执行不回滚

spring事务的使用

sprin的事务处理其实就是通过AOP来实现的,使用

create table user(
    id int primary key AUTO_INCREMENT,
    name varchar(20not null,
    account double 
 )ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 insert into user (name,accountvalues('张三',1000);
 insert into user (name,accountvalues('李四',1000);
<!-- 事务 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>4.3.29.RELEASE</version>
</dependency>

<!-- 事务管理器以及数据源 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.29.RELEASE</version>
</dependency>

<!-- mysql驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.48</version>
</dependency>
事务管理器

spring使用事务管理器来进行事务的管理,最底层的接口是PlatformTransactionManager,主要作用是为应用程序提供事务界定的统一方式,通过该接口,spring为各个平台都提供了对应的事务管理器

public interface PlatformTransactionManager {
 // 根据指定的传播行为,该方法返回当前活动事务或创建一个新的事务
  // TransactionDefinition是事务的定义信息,包括隔离级别、传播行为、超时、只读等设置
  // TransactionStatus事务的状态,包括是否为新事务、是否已提交、是否有保存点、是否回滚等
   TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
// 提交给定的事务和状态
   void commit(TransactionStatus status) throws TransactionException;
// 回滚给定事务
   void rollback(TransactionStatus status) throws TransactionException;

}

关键类TransactionAspectSupport

// 定义了事务属性
public interface TransactionDefinition {
 // 返回传播行为
 default int getPropagationBehavior() {
  return PROPAGATION_REQUIRED;
 }

 // 返回该事务独立于其他事务的工作的程度
 default int getIsolationLevel() {
  return ISOLATION_DEFAULT;
 }

 // 返回以秒为单位的时间间隔,事务必须在该时间间隔内完成
 default int getTimeout() {
  return TIMEOUT_DEFAULT;
 }

 // 该事务是否是只读的
 default boolean isReadOnly() {
  return false;
 }

 // 返回事务的名称
 @Nullable
 default String getName() {
  return null;
 }


 static TransactionDefinition withDefaults() {
  return StaticTransactionDefinition.INSTANCE;
 }

}

根据不同的持久化框架提供不同的实现类

  • 使用mybatis时,实现类为DataSourceTransactionManager
  • 使用Hibernate时,实现类为HibernateTransactionManager
  • 使用JPA时,实现类为JpaTransactionManager
使用注解

在这里采用的是spring中的数据源

<!-- 数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver" />
  <property name="url" value="jdbc:mysql://localhost:3306/spring?useUnicode=true&amp;characterEncoding=utf-8" />
  <property name="username" value="root" />
  <property name="password" value="123456" />
</bean>

<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"/>
</bean>

<!-- 启用事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

当然由于是使用的注解,不要忘记组件扫描

<context:component-scan base-package="com.zhanghe.study.spring4.beans.tx"/>

之后就可以在要保证事务的方法上配置@Transactional以及在该注解上配置相应的事务隔离级别(isolation)、事务传播行为(propagation)、对哪些异常执行回滚(rollbackFor)以及不执行回滚(noRollbackFor) 默认对运行时异常回滚

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
  //指定使用的事务管理器
   @AliasFor("transactionManager")
   String value() default "";

   @AliasFor("value")
   String transactionManager() default "";

   // 设置事务传播行为
   Propagation propagation() default Propagation.REQUIRED;

   // 设置事务隔离级别
   Isolation isolation() default Isolation.DEFAULT;

   // 设置事务超时时间
   int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

   // 读写或只读事务,默认读写
   boolean readOnly() default false;

   // 导致事务回滚的异常类数组
   Class<? extends Throwable>[] rollbackFor() default {};

   // 导致事务回滚的异常类名字数组
   String[] rollbackForClassName() default {};

   // 不会导致事务回滚的异常类数组
   Class<? extends Throwable>[] noRollbackFor() default {};

   // 不会导致事务回滚的异常类名字数组
   String[] noRollbackForClassName() default {};
}
使用XML
<!-- 数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver" />
  <property name="url" value="jdbc:mysql://localhost:3306/spring?useUnicode=true&amp;characterEncoding=utf-8" />
  <property name="username" value="root" />
  <property name="password" value="123456" />
</bean>

<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"/>
</bean>

<!-- 配置事务通知 使用xml配置事务属性 -->
<tx:advice id="txAdvice"  transaction-manager="transactionManager">
    <tx:attributes>
        <!-- 根据方法名指定特定的事务属性 -->
        <tx:method name="get*" read-only="true"/>
        <tx:method name="find*" read-only="true"/>
        <tx:method name="save*" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>


<aop:config>
   <!-- 配置事务切入点 -->
    <aop:pointcut id="pointCut" expression="execution(* com.zhanghe.study.spring4.beans.tx.UserService.*(..))"/>
    <!-- 配置切面 把事务切入点和通知关联起来-->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
</aop:config>

分布式事务

随着业务越来越庞大,有时候可能会采取分库分表的方式来进行处理,那么如果数据都不在一个数据库了,如何进行事务处理呢?那就用到了分布式事务,java的事务规范中提出了JTA来进行分布式事务的处理,而在spring中进行了JTA的实现,在springboot中可以使用spring-boot-starter-jta-atomikos来进行实现

https://zhhll.icu/2021/框架/spring/基础/8.Spring事务/

本文由 mdnice 多平台发布

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

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

相关文章

Hive进阶Day06

目录 一、MapReduce的计算过程 二、Yarn的资源调度 1、yarn的资源调度策略 三、Hive的语法树 四、数据开发 五、数据仓库 六、数据仓库开发流程 七、数仓分层 八、ETL和ELT 一、MapReduce的计算过程 分布式计算框架 需要编写代码执行&#xff0c;执行时会数据所在服务器…

如何正确查看容器的CPU使用率

进入容器中top&#xff0c;虽然看到的PID是容器的&#xff0c;但是%Cpu的统计信息却是宿主机的。 如图 原理 进程的cpu使用率是如何计算出来的&#xff1f; 每个进程的状态是放在文件里的&#xff0c;在/proc目录下&#xff0c;每个进程有自己pid命名的文件夹&#xff0c; …

.NET 爬虫从入门到入狱

目录 前言 1.&#x1f4a1;使用HttpClient爬取数据 2.&#x1f680;模拟User-Agent 3.&#x1f935;使用HTML解析库 3.&#x1f44c;前端Price显示 4.&#x1f331;运行实例 获取金价Au 5.&#x1f9fe;使用正则表达式解析 6.&#x1f4ab;获取BTC价格 7.✨获取CSDN热点…

4.15报错记录

打开文件时出错a bytes-like object is required,notNoneType 确保E:/data/stdata/st- images-1208-json|ST-WT-1.json是一个有效的标签文件。 今天用X-anylabling更改标签目录时出现这个报错 解决方案&#xff1a;图片文件夹中创建同名的一个文件夹把json文件放进去就可以打…

QML语法基础一

import QtQuick QML类型系统 1.基本类型:int bool real double string url list var enum 2.Quick类型:color font matrix4*4 quaternion vector2d vector3d vector4d date point size rect 等 3.javascripte类型:qml支持标准的javascript类型 4.对象类型:用于QML对象实例化 对…

[Qt网络编程]之UDP通讯的简单编程实现

hello&#xff01;欢迎大家来到我的Qt学习系列之网络编程之UDP通讯的简单编程实现。希望这篇文章能对你有所帮助&#xff01;&#xff01;&#xff01; 本篇文章的相关知识请看我的上篇文章: http://t.csdnimg.cn/UKyeM 目录 UDP通讯 基于主窗口的实现 基于线程的实现 UDP通讯…

【YOLO系列PR、F1绘图】更改v5、v7、v8(附v8训练、验证方式),实现调用val.py或者test.py后生成pr.csv,然后再整合绘制到一张图上(使用matplotlib绘制)

目录 1. 前提 效果图2. 更改步骤2.1 得到PR_curve.csv和F1_curve.csv2.1.1 YOLOv7的更改2.1.1.1 得到PR_curve.csv2.2.1.2 得到F1_curve.csv 2.1.2 YOLOv5的更改&#xff08;v6.1版本&#xff09;2.1.3 YOLOv8的更改&#xff08;附训练、验证方式&#xff09; 2.2 绘制PR曲线 …

【创建型模式】抽象工厂模式

一、抽象工厂模式概述 抽象工厂模式定义&#xff1a;提供一个创建一系列相关或相互依赖对象的接口&#xff0c;而无须指定它们具体的类。 模式动机&#xff1a; 1.当系统提供的工厂生产的具体产品并不是一个简单的对象&#xff0c;而是多个位于不同产品等级结构、属于不同类型的…

HiveSql中的函数家族(一)

一.内置函数 1-1 日期类型操作 -- 获取当前日期 select current_date(); -- 获取当前日期时间 select current_timestamp(); -- 获取unix时间&#xff08;时间戳&#xff09; 从1970年1月1号0时0分0秒 到现在过去了多少秒 select unix_timestamp();-- unix时间 和日期时间的转…

41、二叉树-二叉树的层序遍历

思路&#xff1a; 层序遍历就是从左到右依次遍历。这个时候就可以使用队列的方式。例如先把头节点入队&#xff0c;然后遍历开始&#xff0c;首先计算队列长度&#xff0c;第一层&#xff0c;长度为了&#xff0c;遍历一次&#xff0c;依次出队&#xff0c;头结点出队&#xff…

Tomcat和Spring Boot配置https

生成测试证书 生成证书前&#xff0c;先验证本地是否正确配置jdk环境变量&#xff0c;如果jdk环境变量配置正确&#xff0c;在命令行程序输入生成证书的命令。 keytool -genkey -alias tomcat -keyalg RSA -keystore "F:\job\apache-tomcat-8.5.29\key\freeHttps.keysto…

微信小程序之图片上传并保存在服务器

先将图片上传到服务器&#xff0c;后端接口将保存好的图片地址返回给小程序&#xff0c;再将小程序中添加图像的图片的url替换为服务器中照片的存储地址&#xff08;使微信小程序中显示出上传的图片&#xff09;。 1、效果如下&#xff1a; 点击图像后选择图像&#xff1a; 结…

Kafka不仅是消息队列而是一个分布式消息处理平台

目录 1. kafka架构图 2.关键概念解析 2.1 producer 2.2 consumer: 2.3 brkoer 2.4 Topic 与 Partition 2.5 AR (Assigned Replicas) 2.6 ISR(In-Sync Replicas) 2.7 OSR (Out-of-Sync Replicas) 2.8 HW (High Water-mark) 2.9 LEO (Log End Offset)

搜维尔科技:【工业仿真】煤矿机械安全事故VR警示教育系统

产品概述 搜维尔科技 煤矿机械安全事故VR警示教育系统 系统内容&#xff1a; 系统采用虚拟现实技术模拟矿井井下机械安全技术及事故&#xff0c;展现井下常见机械伤害事故&#xff0c;表现伤害事故的隐患点&#xff0c;能够模拟事故发生和发展过程&#xff1b;营造井下灾害发…

如何使用 Node.js 发送电子邮件全解和相关工具推荐

大多数Web应用程序都需要发送电子邮件。它可能用于注册、密码重置、状态报告&#xff0c;甚至是完整的市场营销活动&#xff0c;如新闻和促销。本教程解释了如何在Node.js中发送电子邮件&#xff0c;但其概念和挑战适用于您正在使用的任何系统。 你会在 npm 上找到大量与电子邮…

详细UI色彩搭配方案分享

UI 配色是设计一个成功的用户界面的关键之一。UI 配色需要考虑品牌标志、用户感受、应用程序的使用场景&#xff0c;这样可以帮助你创建一个有吸引力、易于使用的应用程序。本文将分享 UI 配色的相关知识&#xff0c;帮助设计师快速构建 UI 配色方案&#xff0c;以满足企业的需…

windows10小皮安装不同版本composer,实现自由切换使用

1、使用phpstudy小皮面板安装composer1.8.5和composer2.5.8两个版本&#xff1b; 2、打开刚才安装的composer安装目录&#xff1a;D:\phpstudy_pro\Extensions 3、打开composer1.8.5版本&#xff0c;修改composer.bat名称为composer1.8.5.bat&#xff1a; 4、打开composer2.5.8…

隐私计算DataTrust:从产品需求到工程架构实践

继上期介绍了新监管形势下的隐私技术及数据共享合规设计的思考,本期将接着为大家讲解,国内唯一一个获得工信部三项隐私计算测评的产品DataTrust,在隐私计算领域从产品需求到工程架构的实践之路。 随着数据作为第五大生产要素被提出,“数据流通”的社会价值已形成广泛共识,…

Linux命令学习—Apache 服务器(下)

1.7、访问控制、认证授权的综合指令 1.7.1、两种综合情况 1、满足一种条件即可访问 Satisfy any 或者满足访问控制的条件&#xff0c;或者满足认证授权的条件&#xff0c;就可以访问指定页面、目录 2、必须同时满足 2 个条件才能访问 Satisfy all必须同时满足访问控制和认…

vue的实现八股

双向绑定原理 Vue的双向绑定原理是通过数据劫持和观察者模式实现的。 vue使用了响应式的对象&#xff0c;即当数据发生改变的时候&#xff0c;视图也会随之改变 数据劫持&#xff1a; vue2使用了object.definedproperty对数据的每个属性进行劫持&#xff0c;从而逐一对每个…