阶段七-Day04-Spring03

一、Sping声明式事务

1. 编程式事务介绍

整个事务控制的代码都需要程序员自己编写。包含:开启事务(openSession(),创建SqlSession时MyBatis底层自动创建Transaction对象)、提交事务(session.commit())、回滚事务(session.rollback()),像这种整个事务控制代码都需要程序员自己编写的事务叫做编程式事务。

2. 声明式事务介绍

但是当在MyBatis项目中做多个DML操作时,就会发现:上面的代码是固定性套路代码,很多代码是冗余代码

Spring框架发现既然都是固定性代码,就由Spring帮助封装起来。封装后对外让程序员只需进行简单的XMl配置就可以完成事务管理,不再编写事务管理代码。这就是Spring非常重要的功能之一:声明式事务。

3. 声明式事务式底层实现

声明式事务是基于AOP实现的。程序员只需要编写调用持久层代码和业务逻辑代码。把开启事务的代码放在前置通知中,把事务回滚和事务提交的代码放在了后置通知中

相当于把这些冗余的代码通过通知注入到执行sql的方法中,实现事务的控制

二、声明式事务代码演示

1.搭建基本演示环境

1.1 创建项目并配置依赖

新建Maven项目,并配置依赖。

依赖中包含了Mybatis依赖、数据库驱动依赖、Spring核心依赖、Spring整合MyBatis依赖、log4j依赖、spring-test模块依赖、junit4依赖、AOP相关依赖以外,还多了一个新的依赖spring-tx。

 <!-- 事务管理包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.3.16</version>
        </dependency>

4. 如何配置声明式事务

 <!-- 3. 配置事务管理类:Spring封装事务固定套路代码的类-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 事务管理必须连接数据库,需要注入数据源对象 -->
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 2. Spring提供了很多事务控制方法,设定哪个方法应用具体哪种方案 -->
    <!-- 目前只是设定insert方法是一个事务单元,没有具体设定其他详细的事务配置-->
    <!-- 只有方法出现了异常触发异常通知,实现事务回滚,所以绝对不能在service里面try...catch-->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="insert"/>
        </tx:attributes>
    </tx:advice>
    <!-- 1. 设定哪个方法需要被声明式事务管理,使用AOP完成,通过切点定义需要进行声明式事务管理的方法 -->
    <aop:config>
        <aop:pointcut id="mypoint" expression="execution(*  com.sh.service.impl.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="mypoint"></aop:advisor>
    </aop:config>

6. 注解配置声明式事务(常用)

Spring 注解配置事务时,只需要在需要有事务管理的方法上添加@Transactional注解。

必须保证配置注解的方法所在的类已经放入到Spring容器中。

配置注解扫描:

<context:component-scan base-package="com.sh.service.impl"></context:component-scan>

 配置事务管理器类:

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>

使声明式注解生效:

<tx:annotation-driven></tx:annotation-driven>

使用注解配置事务

重要提示:

  1. @TransactionManager 默认寻找叫做transactionManager的事务管理器。如果没有找到会报异常NoSuchBeanDefinitionException。所以,如果希望配置注解时简单点直接写@Transactional就生效,就必须在XML配置事务管理器时,id必须叫做transactionManager。

  2. 如果在XML配置事务管理器时,id不叫transactionManager,需要在@Transactional(transactionManager="XML配置时id值")。

  3. @Transactional用在类上,整个类中方法都生效。

  4. @Transactional用在方法上,该方法生效。用在方法上优先级更高。

声明式事务的属性,注解和配置文件都有,注解更多

name属性: 配置哪些方法需要事务控制,支持通配符

readonly属性 : 是否为只读事务 ,常用与查询操作 @Transaction(readonly = true)

rollback-for属性:异常类型全限定路径,表示出现什么类型的异常进行数据回滚。

no-rollback-for属性:定义出现的异常出现了不处理

四、事务传播行为(面试题)

事务传播行为:当出现service的方法调用另一个service方法时(这些方法都被声明式事务管理),这些方法如何进行事务管理。

注意:

1. 默认情况下都认为每个方法都是没有事务的(事务自动提交)。

2. 整个调用最终都是在调用者里面统一提交回滚。

3. 在声明式事务中,如果是同一个类的多个方法相互调用,属于同一个事务。

4. 如果希望测试效果,必须把方法放入到多个不同的业务类中进行测试。

@Transactional(propagation = 中设置)

REQUIRED(默认值):如果当前有事务则加入到事务中。如果当前没有事务则新增事务。

NEVER:必须在非事务状态下执行,如果当前没有事务,正常执行,如果当前有事务,报错。

NESTED:必须在事务状态下执行。如果没有事务,新建事务,如果当前有事务,创建一个嵌套事务(子事务)。

REQUIRES_NEW:必须在事务中执行,如果当前没有事务,新建事务,如果当前有事务,把当前事务 挂起, 重新建个事务。(调用者统一提交回滚)

SUPPORTS:如果当前有事务就在事务中执行,如果当前没有事务,就在非事务状态下执行。

NOT_SUPPORTED:必须在非事务下执行,如果当前没有事务,正常执行,如果当前有事务,把当前 事务挂起。

MANDATORY:必须在事务内部执行,如果当前有事务,就在事务中执行,如果没有事务,报错。(可 以配置在入口方法)

五、事务隔离级别(面试题)

多个事务同时操作数据库时,允许多个事务操作的方式就是事务隔离级别。事务隔离级别主要是通过添加锁操作实现的。事务隔离级别主要是解决高并发下脏读、幻读、不可重复读问题的。

事务隔离级别出现场景:高并发场景。

Java主要做的就是Web项目(服务端项目),每次客户端发送的都叫请求。运行多人同时请求,每个请求运行同一个方法实际上是多个事务。

脏读:

事务A没有提交事务,事务B读取到事务A未提交的数据,这个过程称为脏读。读取到的数据叫做脏数据。

不可重复读:

当事务A读取到表中一行数据时,同时另一个事务修改这行数据,事务A读取到的数据和表中真实数据不一致。

幻读:

事务A对表做查询全部操作,事务B向表中新增一条数据。事务A查询出来的数据和表中数据不一致,称为幻读。

@Transactional中设置属性isolation的值来进行配置。(select @@transaction_isolation查询数据库支持的事务隔离级别)

isolation可取值分别为:

DEFAULT:

表示用数据库的隔离级别,MySQL8默认的事务隔离级别REPEATABLE_READ。

READ_UNCOMMITTED:

读未提交(脏读,幻读,不可重复读)。

READ_COMMITTED:

读已提交(幻读,不可重复读)。

REPEATABLE_READ:

可重复读(幻读)。

MySQL采用了MVCC版本控制:

1. 不添加锁的读,快照读(读取的数据状态进行临时存储,快照读读取临时数据),解决幻读

2.加锁读,必须读取数据库中的数据,出现幻读

MySQL中锁机制:

1. 显示锁:
 1. 执行查询默认不使用锁

2. 查询时使用锁

1. 查询sql for update; 添加排他锁

2. 查询sql lock in share mode; 添加了共享锁

2.自动锁:添加,修改,删除 自动添加排它锁

SERIALIZABLE

串行读来通过牺牲性能解决脏读、不可重复度、幻读问题。

六、属性配置文件

1. 属性配置文件

现在我们在配置applicationcontext.xml的时候是直接将数据源参数在配置文件中直接配置的,就是数据库的链接参数。spring也提供了一种解耦合的配置方式,就是将数据源中的数据库链接参数单独的写在一个配置文件中。

配置文件需要直接声明在src目录下,文件名随意。键名任意,但是用户名不能使用username,可能会和系统的变量冲突。

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/account?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai
user=root
password=root

applicationcontext.xml配置文件:

<!--配置参数配置文件路径-->
 <context:property-placeholder location="classpath:db.properties"/>
<!--配置数据源bean-->
<bean id="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource">
     <property name="driverClassName" value="${driver}"></property>
     <property name="url" value="${url}"></property>
     <property name="username" value="${user}"></property>
     <property name="password" value="${password}"></property>
 </bean>

七、获取属性文件中的值

@Value

作用:用来替换配置文件中的属性注入的。

使用:在属性上声明,值为${“键名”}

注意:使用此注解的注入,无需提供get/set方法。

@Component("u")
public class User {
    @Value("1")
    private Integer uid;
    @Value("${driver}")
    private String uname;
    private String pwd;
	......
}

八、Bean的生命周期(面试题)

Spring中Bean的生命周期就是指Bean从初始化到销毁的过程。Bean最简单的实现就是直接使用<bean>标签定义这个Bean。

<bean id="user" class="com.sh.pojo.User"></bean>

1. 生命周期流程图

在这种情况下会调用类的构造方法进行实例化。

  1. 通过标签的init-method和destory-method自定义初始化和销毁方法。

  2. 实现各种Aware接口,例如BeanNameAware、BeanFactoryAware、ApplicationContextAware等,可以获取bean名字信息,bean工厂信息,容器信息。

  3. 通过InitializingBean,DisposableBean实例化Bean和销毁Bean。

  4. 通过BeanFactoryPostProcessor,BeanPostProcessor进行增强。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Shotcut for Mac/Win:免费的开源视频编辑软件

Shotcut 是一款免费的开源视频编辑软件&#xff0c;允许用户为各种目的编辑和创建视频。它适用于 Windows、Mac 和 Linux 操作系统。Shotcut 具有用户友好的界面&#xff0c;并提供一系列功能&#xff0c;例如支持多种视频格式、音频过滤器和视频效果。 Shotcut的一些主要功能…

C++拷贝构造函数和运算符重载

目录 一&#xff0c;拷贝构造函数 二&#xff0c;运算符重载 一&#xff0c;拷贝构造函数 概念&#xff1a;在类的定义中&#xff0c;构造函数只是单纯将内置类型进行初始化&#xff0c;而拷贝构造函数是将整个类进行拷贝到另一个类中进行初始化。在定义拷贝构造函数时&…

bclinux aarch64 ceph 14.2.10 文件存储 Ceph File System, 需要部署mds: ceph-deploy mds

创建池 [rootceph-0 ~]# ceph osd pool create cephfs_data 64 pool cephfs_data created [rootceph-0 ~]# ceph osd pool create cephfs_metadata 32 pool cephfs_metadata created cephfs_metadata 64 报错 官方说明&#xff1a; 元数据池通常最多可容纳几 GB 的数据。为…

Web后端开发_01

Web后端开发 请求响应 SpringBoot提供了一个非常核心的Servlet 》DispatcherServlet&#xff0c;DispatcherServlet实现了servlet中规范的接口 请求响应&#xff1a; 请求&#xff08;HttpServletRequest&#xff09;&#xff1a;获取请求数据响应&#xff08;HttpServletRe…

正点原子嵌入式linux驱动开发——Linux DAC驱动

上一篇笔记中学习了ADC驱动&#xff0c;STM32MP157 也有DAC外设&#xff0c;DAC也使用的IIO驱动框架。本章就来学习一下如下在Linux下使用STM32MP157上的DAC。 DAC简介 ADC是模数转换器&#xff0c;负责将外界的模拟信号转换为数字信号。DAC刚好相反&#xff0c;是数模转换器…

MS512非接触式读卡器 IC

MS512 是一款应用于 13.56MHz 非接触式通信中的高集 成度读写卡芯片。它利用了先进的调制和解调技术&#xff0c;完全集 成了在 13.56MHz 下的各种非接触式通信方式和协议。 主要特点  高度集成的解调和解码模拟电路  采用少量外部器件&#xff0c;即可将输出驱动级接…

# Spring事务与分布式事务

一、事务的具体定义 事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元&#xff0c;组成事务的所有操作只有在所有操作均能正常执行的情况下方能提交&#xff0c;只要其中任一操作执行失败&#xff08;出现异常&#xff09;&#xff0c;都将导致整个事务…

联想笔记本Fn + A可以全选,Ctrl失效

问题&#xff1a;联想笔记本Fn A可以全选&#xff0c;ctrl失效。 原因&#xff1a;BIOS启用了Fn键和Ctrl键互换。 解决操作&#xff1a; 1.开机时一直按F2&#xff0c;进入BIOS 2.点击More Settings > 2.选取Configuration 3.将Fool Proof Fn Ctrl 设定变更为Disabled 4.按…

【Linux】进程概念IV 进程地址空间

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法…感兴趣就关注我吧&#xff01;你定不会失望。 本篇导航 0. 数据在内存中的分布1. 虚拟地址与真实物理地址2. 进程地址空间2.1 进程地址空间概念2.2 进程->页表->内存 0. 数据在内…

MASK、MPSK、MFSK信号的调制与解调+星座图

MASK、MPSK、MFSK信号的调制与解调星座图 本文主要涉及多进制幅度键控&#xff08;MASK&#xff09;、多进制相移键控&#xff08;MPSK&#xff09;、多进频移键控&#xff08;MFSK&#xff09;的调制与解调&#xff0c;同时涉及到星座图的分析。 关于通信原理还有其他文章可参…

【SpringBoot整合JSP】

【源码】SpringBoot整合JSP 一、前言二、创建web项目,webapp 【创建视图层】&#xff08;一&#xff09;在 main 目录下相关目录1. 点击 “FIle”-> “Project Structure”&#xff0c;选择 “Model”-> “Web”&#xff0c;将“Web Resource Directory”的路径修改为 刚…

JOSEF约瑟 反时限过流继电器JGL-115板前接线5A速断保护

系列型号 JGL-111反时限过流继电器&#xff1b;JGL-112反时限过流继电器&#xff1b; JGL-113反时限过流继电器&#xff1b;JGL-114反时限过流继电器&#xff1b; JGL-115反时限过流继电器&#xff1b;JGL-116反时限过流继电器&#xff1b; JGL-117反时限过流继电器&#xff1b…

Python数据大杀器:掌握collections与heapq,编写更高效的算法与数据处理

前言 在计算机科学的世界中&#xff0c;数据结构是构建强大和高效算法的基石。Python作为一门广泛应用的编程语言&#xff0c;以其丰富的数据结构模块为程序员提供了强大的工具。本文旨在深入研究Python的collections和heapq模块&#xff0c;通过更丰富的示例和详细的解释&…

竞赛 题目:基于FP-Growth的新闻挖掘算法系统的设计与实现

文章目录 0 前言1 项目背景2 算法架构3 FP-Growth算法原理3.1 FP树3.2 算法过程3.3 算法实现3.3.1 构建FP树 3.4 从FP树中挖掘频繁项集 4 系统设计展示5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于FP-Growth的新闻挖掘算法系统的设计与实现…

JavaScript 基本数据类型

字符串 在JS中&#xff0c;数据类型有&#xff1a;字符串、数字、布尔、数组、对象、Null、Undefined 用到最多的还是字符串和数组的转换。 <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>首页</title><style&g…

Rust语言做数据抓取代码示例

这个任务需要使用到Rust语言和网络爬虫相关的库&#xff0c;以下是一个简单的示例代码。请注意&#xff0c;由于涉及到的具体问题和数据的复杂性&#xff0c;这个示例可能并不能直接满足你的需求&#xff0c;需要根据你的具体情况进行修改和扩展。 use reqwest; use serde::{De…

Splashtop 如何维护 GDPR 合规性

2018年&#xff0c;欧盟颁布了一项新法律&#xff0c;以保护欧洲公民的个人数据免遭任何收集数据的人不当处理。这可能意味着企业和组织&#xff0c;包括面对面和虚拟形式。这项开创性的法律为其他立法铺平了道路&#xff0c;例如加利福尼亚州的《加州消费者隐私法》&#xff0…

linux线程

文章目录 前言一、线程1、线程概念2、线程使用2.1 pthread_create2.2 线程共享数据和私有数据2.3 为什么线程切换的成本更低&#xff1f; 3、线程性质3.1 线程的优点3.2 线程的缺点3.3 线程异常3.4 线程用途 4、vfork接口 二、线程控制1、线程创建2、线程等待3、线程退出4、线程…

行业追踪,2023-11-13

自动复盘 2023-11-13 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

集成Line、Facebook、Twitter、Google、微信、QQ、微博、支付宝的三方登录sdk

下载地址&#xff1a; https://githubfast.com/anerg2046/sns_auth 安装方式建议使用composer进行安装 如果linux执行composer不方便的话&#xff0c;可以在本地新建个文件夹&#xff0c;然后执行上面的composer命令&#xff0c;把代码sdk和composer文件一起上传到项目适当位…