2024.10月14日-SpringMVC-基于注解声明式事务的属性

devtools/2024/10/22 2:03:34/

一、基于注解的声明式事务5个属性

1 只读

语法:

@Transactional(readOnly = true)

意义:

对一个查询操作来说,如果我们把它设置成只读,就能够明确告诉数据库,这个操作不涉及写操作。这样数据库就能够针对查询操作来进行优化
对增删改操作设置只读会抛出下面异常:Caused by: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed

2 超时

语法:

@Transactional(timeout = 3)

意义:

事务在执行过程中,有可能因为遇到某些问题,导致程序卡住,从而长时间占用数据库资源。而长时间占用资源,大概率是因为程序运行出现了问题(可能是Java程序或MySQL数据库或网络连接等等)。
此时这个很可能出问题的程序应该被回滚,撤销它已做的操作,事务结束,把资源让出来,让其他正常程序可以执行。
概括来说就是一句话:超时回滚,释放资源。

3 回滚策略

声明式事务默认只针对运行时异常回滚,编译时异常不回滚。 可以通过@Transactional中相关属性设置回滚策略

  • rollbackFor属性:需要设置一个异常类的Class对象

  • rollbackForClassName属性:需要设置一个字符串类型的全类名

  • noRollbackFor属性:需要设置一个Class类型的对象

  • noRollbackFor属性:需要设置一个字符串类型的全类名

语法:

@Transactional(noRollbackFor = ArithmeticException.class)

4 事务隔离级别

数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。一个事务与其他事务隔离的程度称为隔离级别。SQL标准中规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。

隔离级别一共有四种:

  • 读未提交(READ UNCOMMITTED): 允许Transaction01读取Transaction02未提交的修改。

  • 读已提交(READ COMMITTED): 要求Transaction01只能读取Transaction02已提交的修改。

  • 可重复读(REPEATABLE READ):确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其它事务对这个字段进行更新。(MySQL默认为可重复读。)

  • 串行化(SERIALIZABLE):确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其它事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。

语法:

@Transactional(isolation = Isolation.DEFAULT)//使用数据库默认的隔离级别
@Transactional(isolation = Isolation.READ_UNCOMMITTED)//读未提交
@Transactional(isolation = Isolation.READ_COMMITTED)//读已提交
@Transactional(isolation = Isolation.REPEATABLE_READ)//可重复读
@Transactional(isolation = Isolation.SERIALIZABLE)//串行化

5 事务传播

语法:

@Transactional(propagation = Propagation.REQUIRED)

传播的概念:

事务传播:指的是调用者将自己事务传递给被调用者,比如A.fa()里调用了B.fb():    
A.fa(){B.fb();
}
​
A的方式的事务传播给了B的方法事务

七个值:研究的对象是B的方法事务如何被A的方式事务影响的。 因此B的方法的设置可能是如下七个值中的一个

1. PROPAGATION_REQUIRED:默认值    (外面影响里面,里面不影响外面)
​A有事务, 则B加入A的当前事务。  合成一个事务。有异常就整体回滚。A没有事务,B就使用自己的事务。
​
2. PROPAGATION_REQUIRES_NEW:(外面不影响里面,里面(不)影响外面)若A的方法有事务,  B就新建事务,使用新建的,将A的事务挂起。 如果B执行完了,A的后续代码继续使用A的事务若A的方法没有事务,B就新建事务,使用新建的。
​
3. PROPAGATION_NESTED :(外面的影响里面的,里面的(不)影响外面的)若A的方法有事务, B就在嵌套一个相同事务。如果B的方法抛出异常,则B回滚如果A的方法不捕获异常,则回滚,捕获则不回滚如果A的方法抛出异常,则都回滚
​
4. PROPAGATION_SUPPORTS:(外面的影响里面的,里面的影响外面的)如果A有事务,B就用A的事务。A的方法抛出异常,A和B都会回滚。B的方法抛出异常,A和B都会回滚。如果A没有事务,B就没收到事务。因此A和B都没有事务,则A和B的运行出现异常都不会回滚​
5. PROPAGATION_NOT_SUPPORTED:如果A没有事务,B就以非事务方式执行,如果A有,B就将A传过来的事务的挂起。白话:  A有没有事务,B都不使用。
6. PROPAGATION_NEVER:如果A没有事务,就以非事务方式执行,如果有,就抛出异常。  白话:我都说了不要了,你非给我,我就错给你看
​
7. PROPAGATION_MANDATORY:(外面的影响里面的,里面的影响外面的)如果A没有事务,B就抛出异常,如果A有事务,B就使用A的当前事务。  白话:我强制需要事务,你不传给我,我就错给你看如果A有事务如果A的方法抛出异常,则A和B都会回滚如果B的方法抛出异常,则A和B也都会回滚
​
Spring框架定义了七种事务传播行为:
​
•Propagation.REQUIRED•(默认):所修饰的方法必须运行在事务中。当调用方抛出异常时,被调的方法也会回滚。
•Propagation.REQUIRES_NEW•:所修饰的方法只会运行在它自己的事务中,与调用方的事务互不影响。调用方抛出异常时,被调方法不会回滚。
•Propagation.SUPPORTS•:所修饰的方法自身不运行在事务中,若调用方有事务,则运行在调用方的事务中;若无事务,则以非事务方式运行。
•Propagation.MANDATORY•:所修饰的方法必须在事务中运行。若调用方无事务,则抛出异常并回滚。
•Propagation.NOT_SUPPORTED•:以非事务方式执行操作,若当前存在事务,则将当前事务挂起。
•Propagation.NEVER•:以非事务方式运行,若调用方有事务,则抛出异常。
•Propagation.NESTED•:若调用方有事务,则嵌套事务内执行;若无事务,则执行与PROPAGATION_REQUIRED类似的操作•2。
这些传播行为帮助开发者在复杂的调用关系中更好地控制事务行为,确保数据的一致性和安全性•

二、基于XML的声明式事务

<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.3.1</version>
</dependency>
<!--  注册事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="ds"/>
</bean>
​
<!-- tx:advice标签:配置事务通知id属性:给事务通知标签设置唯一标识,便于引用transaction-manager属性:关联事务管理器 -->
<tx:advice id="txAdvice" transaction-manager="txManager"><tx:attributes><!--  tx:method标签:配置具体的事务方法name属性:指定方法名,可以使用星号代表多个字符 --><tx:method name="find*" read-only="true" timeout='3'/><tx:method name="query*" read-only="true"/><tx:method name="toUpdate*" read-only="true"/><!--  read-only属性:设置只读属性rollback-for属性:设置回滚的异常 no-rollback-for属性:设置不回滚的异常isolation属性:设置事务的隔离级别timeout属性:设置事务的超时属性propagation属性:设置事务的传播行为 --><tx:method name="buy*" read-only="false" rollback-for="java.lang.Exception" propagation="REQUIRED"/></tx:attributes>
</tx:advice>
​
<aop:config><!-- 配置事务通知和切入点表达式 --><aop:advisor advice-ref="txAdvice" pointcut="execution(* com.service.*.*(..))"></aop:advisor>
</aop:config>
​

http://www.ppmy.cn/devtools/127703.html

相关文章

xRDP – 在 Ubuntu 18.04、20.04、22.04、22.10、23.04(脚本版本 1.4.7)上轻松安装 xRDP

最新脚本Repository | c-nergy.be 概述 到目前为止&#xff0c;您应该知道 xrdp-installer 脚本旨在简化 xRDP 在 Ubuntu 操作系统上的安装和配置后操作。xRDP 是一款在 Linux 上启用远程桌面服务的软件。这意味着 Windows 用户可以使用他们的远程桌面客户端 &#xff08;mst…

深入探讨:Java 中的值传递与引用传递,真相究竟如何?

文章目录 什么是值传递和引用传递&#xff1f;Java 中的传递机制&#xff1a;值传递的真相1. 基本类型的传递&#xff1a;值传递2. 对象类型的传递&#xff1a;也是值传递&#xff01; 引用的陷阱&#xff1a;为什么它是值传递&#xff1f;总结&#xff1a;如何更好地理解 Java…

CEEMDAN +组合预测模型(CNN-Transformer + ARIMA)

往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较 全是干货 | 数据集、学习资料、建模资源分享&#xff01; EMD、EEMD、FEEMD、CEEMD、CEEMDAN的区别、原理和Python实现&#xff08;一&#xff09;EMD-CSDN博客 EMD、EEM…

repo 命令大全详解(第十一篇 repo init)

repo forall 命令用于在指定的项目上执行给定的命令&#xff0c;非常适合批量操作。 参数分类及解释 基本参数 [<project>...]: 可选&#xff0c;指定要操作的项目。如果不指定&#xff0c;则对所有项目执行命令。 示例: repo forall my_project -c "git status&q…

oracle查询数据库占用大小

查询表咋用大小 SELECTSUM(bytes)/1024/1024/1024 AS GB FROMdba_segments WHEREsegment_type TABLE;查询所有文件占用大小 SELECTROUND(SUM(bytes) / 1024 / 1024 / 1024, 2) AS "Size in GB" FROMdba_data_files;查询每个表空间大小 SELECTtablespace_name,ROUN…

Milvus 到 TiDB 向量迁移实践

作者&#xff1a; caiyfc 原文来源&#xff1a; https://tidb.net/blog/e0035e5e 一、背景 我最近在研究使用向量数据库搭建RAG应用&#xff0c;并且已经使用 Milvus、Llama 3、Ollama、LangChain 搭建完成。最近通过活动获取了 TiDB Cloud Serverless 使用配额&#xff…

Elasticsearch入门:增删改查详解与实用场景

引言 在我之前做社交架构设计的时候&#xff0c;我们有一项关键且必要的需求&#xff1a;需要存储并记录用户的所有聊天记录。这些记录不仅用于业务需求&#xff0c;也承担了风控审查的职责。因此&#xff0c;在架构设计中&#xff0c;我们需要考虑每天海量的聊天消息量&#…

滚雪球学Redis[6.3讲]:Redis分布式锁的实战指南:从基础到Redlock算法

全文目录&#xff1a; &#x1f389;前言&#x1f6a6;Redis分布式锁的概念与应用场景&#x1f343;1.1 什么是分布式锁&#xff1f;&#x1f342;1.2 应用场景 ⚙️使用Redis实现分布式锁&#x1f33c;2.1 基本思路&#x1f33b;2.2 示例代码&#x1f940;2.3 代码解析 &#…