spring(七):事务操作

news2025/2/26 15:05:30

spring(七):事务操作

  • 前言
  • 一、什么是事务
  • 二、事务四个特性(ACID)
  • 三、事务操作(搭建事务操作环境)
  • 四、事务操作(Spring 事务管理介绍)
  • 五、事务操作(注解声明式事务管理)
  • 六、事务操作(声明式事务管理参数配置)
      • 1、@Transactional
      • 2、propagation:事务传播行为
      • 3、ioslation:事务隔离级别
      • 4、timeout:超时时间
      • 5、readOnly:是否只读
      • 6、rollbackFor:回滚
      • 7、noRollbackFor:不回滚
  • 七、事务操作(XML 声明式事务管理)
  • 八、事务操作(完全注解声明式事务管理)



前言

本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注博主!也许一个人独行,可以走的很快,但是一群人结伴而行,才能走的更远!

一、什么是事务

⭕ 事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败所有操作都失败

⭕ 典型场景:银行转账

  • lucy 转账 100 元 给 mary
  • lucy 少 100,mary 多 100

二、事务四个特性(ACID)

⭕原子性
⭕一致性
⭕隔离性
⭕持久性

三、事务操作(搭建事务操作环境)

在这里插入图片描述

① 创建数据库表,添加记录

② 创建 service,搭建 dao,完成对象创建和注入关系
service 注入 dao,在 dao 注入 JdbcTemplate,在 JdbcTemplate 注入 DataSource

@Service
public class UserService {
 //注入 dao
 @Autowired
 private UserDao userDao; }
@Repository
public class UserDaoImpl implements UserDao {
 @Autowired
 private JdbcTemplate jdbcTemplate; }

③ 在 dao 创建两个方法:多钱和少钱的方法,在 service 创建方法(转账的方法)

@Repository
public class UserDaoImpl implements UserDao {
 @Autowired
 private JdbcTemplate jdbcTemplate;
 //lucy 转账 100 给 mary
 //少钱
 @Override
 public void reduceMoney() {
 String sql = "update t_account set money=money-? where username=?";
 jdbcTemplate.update(sql,100,"lucy");
 }
 //多钱
 @Override
 public void addMoney() {
 String sql = "update t_account set money=money+? where username=?";
 jdbcTemplate.update(sql,100,"mary");
 } }
@Service
public class UserService {
 //注入 dao
 @Autowired
 private UserDao userDao;
 //转账的方法
 public void accountMoney() {
 //lucy 少 100
 userDao.reduceMoney();
 //mary 多 100
 userDao.addMoney();
 } }

④ 上面代码,如果正常执行没有问题的,但是如果代码执行过程中出现异常,有问题

  public void accountMoney(int money){
        userDao.reduceMoney(money);
        int number = 10 / 0;
        userDao.addMoney(money);
    }

上面问题如何解决呢?
使用事务进行解决

⑤ 事务操作过程

//转账的方法
    public void accountMoney() {
//        try {
            //第一步 开启事务

            //第二步 进行业务操作
            //lucy少100
            userDao.reduceMoney();

            //模拟异常
            int i = 10/0;

            //mary多100
            userDao.addMoney();

            //第三步 没有发生异常,提交事务
//        }catch(Exception e) {
            //第四步 出现异常,事务回滚
//        }
    }

四、事务操作(Spring 事务管理介绍)

⭕ 事务添加到 JavaEE 三层结构里面 Service 层(业务逻辑层)

⭕ 在 Spring 进行事务管理操作 有两种方式:
编程式事务管理和声明式事务管理(使用)

⭕ 声明式事务管理
(1)基于注解方式(使用)
(2)基于 xml 配置文件方式

⭕ 在 Spring 进行声明式事务管理,底层使用 AOP 原理

⭕ Spring 事务管理 API
(1)提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类

在这里插入图片描述

五、事务操作(注解声明式事务管理)

1、在 spring 配置文件配置事务管理器

<!--创建事务管理器--> 
<bean id="transactionManager" 
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <!--注入数据源-->
 <property name="dataSource" ref="dataSource"></property>
</bean>

2、在 spring 配置文件,开启事务注解
(1)在 spring 配置文件引入名称空间 tx

<beans xmlns="http://www.springframework.org/schema/beans" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:context="http://www.springframework.org/schema/context" 
 xmlns:aop="http://www.springframework.org/schema/aop" 
 xmlns:tx="http://www.springframework.org/schema/tx" 
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd 
 http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context.xsd 
 http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop.xsd 
 http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx.xsd">

(2)开启事务注解

<!--开启事务注解--> 
<tx:annotation-driven transactionmanager="transactionManager"></tx:annotation-driven>

3、在 service 类上面(或者 service 类里面方法上面)添加事务注解
(1)@Transactional,这个注解添加到类上面,也可以添加方法上面
(2)如果把这个注解添加类上面,这个类里面所有的方法都添加事务
(3)如果把这个注解添加方法上面,为这个方法添加事务

@Service
@Transactional
public class UserService {

六、事务操作(声明式事务管理参数配置)

1、@Transactional

在 service 类上面添加注解@Transactional,在这个注解里面可以配置事务相关参数

在这里插入图片描述

2、propagation:事务传播行为

(1)多事务方法直接进行调用,这个过程中事务 是如何进行管理的

在这里插入图片描述
在这里插入图片描述

@Service
@Transactional(propagation = Propagation.REQUIRED)//默认也是Propagation.REQUIRED
public class UserService {

3、ioslation:事务隔离级别

(1)事务有特性成为隔离性,多事务操作之间不会产生影响。不考虑隔离性产生很多问题
(2)有三个读问题:脏读、不可重复读、虚(幻)读
(3)脏读:一个未提交事务读取到另一个未提交事务的数据
(4)不可重复读:一个未提交事务读取到另一提交事务修改数据
(5)虚读:一个未提交事务读取到另一提交事务添加数据

在这里插入图片描述

解决:通过设置事务隔离级别,解决读问题

在这里插入图片描述

@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)
public class UserService {

4、timeout:超时时间

(1)事务需要在一定时间内进行提交,如果不提交进行回滚
(2)默认值是 -1 ,设置时间以秒单位进行计算

5、readOnly:是否只读

(1)读:查询操作,写:添加修改删除操作
(2)readOnly 默认值 false,表示可以查询,可以添加修改删除操作 (3)设置readOnly 值是 true,设置成 true 之后,只能查询

6、rollbackFor:回滚

(1)设置出现哪些异常进行事务回滚

7、noRollbackFor:不回滚

(1)设置出现哪些异常不进行事务回滚

@Transactional(readOnly = false,timeout = -1,propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)
public class UserService {}

七、事务操作(XML 声明式事务管理)

1、在 spring 配置文件中进行配置
第一步 配置事务管理器
第二步 配置通知
第三步 配置切入点和切面

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 组件扫描 -->
    <context:component-scan base-package="com.atguigu"></context:component-scan>

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="jdbc:mysql:///user_db" />
        <property name="username" value="root" />
        <property name="password" value="root" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    </bean>

    <!-- JdbcTemplate对象 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--注入dataSource-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--1 创建事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--2 配置通知-->
    <tx:advice id="txadvice">
        <!--配置事务参数-->
        <tx:attributes>
            <!--指定哪种规则的方法上面添加事务-->
            <tx:method name="accountMoney" propagation="REQUIRED"/>
            <!--<tx:method name="account*"/>-->
        </tx:attributes>
    </tx:advice>

    <!--3 配置切入点和切面-->
    <aop:config>
        <!--配置切入点-->
        <aop:pointcut id="pt" expression="execution(* com.atguigu.spring5.service.UserService.*(..))"/>
        <!--配置切面-->
        <aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
    </aop:config>
</beans>

八、事务操作(完全注解声明式事务管理)

1、创建配置类,使用配置类替代 xml 配置文件

@Configuration //配置类
@ComponentScan(basePackages = "com.atguigu") //组件扫描
@EnableTransactionManagement //开启事务
public class TxConfig {

    //创建数据库连接池
    @Bean
    public DruidDataSource getDruidDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///user_db");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }

    //创建JdbcTemplate对象
    @Bean
    public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
        //到ioc容器中根据类型找到dataSource
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        //注入dataSource
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }

    //创建事务管理器
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}

测试:

    public void testAccount() {

        ApplicationContext context =
                new AnnotationConfigApplicationContext(TxConfig.class);
        UserService userService = context.getBean("userService", UserService.class);
        userService.accountMoney();
    }

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

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

相关文章

SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】

文章目录前言1、分布式情况下如何加锁2、具体实现过程3、测试3.1 一个服务按照多个端口同时启动3.2 使用jmeter进行压测前言 上一篇实现了单体应用下如何上锁,这一篇主要说明如何在分布式场景下上锁 上一篇地址:加锁 1、分布式情况下如何加锁 需要注意的点是: 在上锁和释放…

C/C++每日一练(20230412)

目录 1. 二维数组找最值 &#x1f31f;&#x1f31f; 2. 排序 &#x1f31f; 3. 二叉树展开为链表 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 二维…

使用ebpf 监控golang 应用

一、背景 使用ebpf 监控grpc-go的应用&#xff0c;grpc-go http2 client的处理点 func (l *loopyWriter) writeHeader(streamID uint32, endStream bool, hf []hpack.HeaderField, onWrite func()) error { ...... }// operateHeaders takes action on the decoded headers. f…

大数据 | Hadoop集群搭建(完全分布式)

知识目录一、前言二、配置三台虚拟机2.1 克隆三台虚拟机2.2 配置克隆的虚拟机2.3 使用Xshell连接虚拟机2.4 配置SSH免密登录三、Hadoop集群准备3.1 安装 rsync3.2 安装xsync分发脚本3.3 安装JDK和安装Hadoop3.4 配置环境变量3.5 分发四、Hadoop集群搭建4.1 修改配置文件4.2 配置…

Python数据分析案例24——基于深度学习的锂电池寿命预测

本期开始案例较为硬核起来了&#xff0c;适合理工科的硕士&#xff0c;人文社科的同学可以看前面的案例。 案例背景 这篇文章是去年就发了&#xff0c;刊物也印刷了&#xff0c;现在分享一部分代码作为案例给需要的同学。 原文链接&#xff08;知网文章 C核&#xff09;&…

OSPF的优化

O_ASE --- 标志域外路由信息 --- 因为域外的路由信息不可控性较强&#xff0c;所以&#xff0c;信任程度较低&#xff0c;我们将其优先级设置为150。 LSA --- 链路状态通告 --- OSPF协议在不同网络环境下产生的用于携带和传递不同的信息。 LSDB --- 链路状态数据库 SPF --- 最短…

【数据分析实战】基于python对Airbnb房源进行数据分析

文章目录&#x1f4da;引言&#x1f4d6;数据加载以及基本观察&#x1f4c3;缺失值观察及处理&#x1f516;缺失值观察以及可视化&#x1f516;缺失值处理&#x1f4c3;异常值观察及处理&#x1f4d6;数据探索&#x1f4a1;哪个区域的房源最受欢迎&#xff1f;&#x1f4a1;哪种…

基于opencv的边缘检测方法

1、梯度运算 用OpenCV的形态变换&#xff08; 膨胀、腐蚀、开运算和闭运算&#xff09;函数morphologyEx 梯度运算即膨胀结果-腐蚀结果&#xff1a; 【注意】对于二值图像来说&#xff0c;必须是前景图像为白色&#xff0c;背景为黑色&#xff0c;否则需要进行反二值化处理 …

Mybatis【第一个 Mybatis 程序】

目录 一、Maven 环境配置 1、配置 pom.xml 1.1、依赖的 jar包 1.2、防止资源导出失败 2、在resources下编写 Mybatis核心配置文件 二、搭建结构 1、编写mybatis工具类&#xff08;utils&#xff09; 2、编写实体类&#xff08;pojo&#xff09; 3、Mybatis 的实现&…

【Vue3实践】(六)Vue3使用vite处理环境变量、打包部署、nginx配置

文章目录1.前言2.环境变量2.1.环境变量文件(.env)2.2.环境变量变量定义与使用3.打包部署3.1.nginx配置3.2.静态站点根路径配置4.总结1.前言 由于在日常开发中会有一部分前端的开发任务&#xff0c;会涉及到Vue的项目的搭建、迭代、构建发布等操作&#xff0c;所以想系统的学习…

Linux:主机USB设备驱动简析

文章目录1. 前言2. 分析背景3. USB 总线硬件拓扑4. USB 协议栈概览4.1 Linux USB 子系统概览4.2 USB外设(如U盘)固件基础5. Linux USB 子系统初始化6. Linux USB 主机控制器(HCD) 驱动6.1 USB 主机控制器驱动初始化6.2 USB 主机控制器设备对象注册和驱动加载7. Linux USB 设备驱…

Chatgpt接入Csdn:实现自动回复、评论、点赞

背景 起初&#xff0c;我只是想自己弄个工具&#xff0c;用来处理一下大佬们的三连支持&#xff0c;后面我发现大家都在讨论chatgpt&#xff0c;于是我将自动回复和评论消息接入到了Csdn中&#xff0c;不知道这篇文章能不能发出来&#xff0c;代码的话暂时不开源&#xff0c;后…

【从零开始】Docker Desktop:听说你小子要玩我

前言 &#x1f34a;缘由 捡起遗忘的Docker知识 由于本狗近期项目紧任务重&#xff0c;高强度的搬砖导致摸鱼时间下降。在上线项目时&#xff0c;看到运维大神一系列骚操作&#xff0c;dockerk8s的知识如过眼云烟&#xff0c;忘得干净的很。所以想重新恶补一下docker知识&…

深度学习中的卷积神经网络

博主简介 博主是一名大二学生&#xff0c;主攻人工智能研究。感谢让我们在CSDN相遇&#xff0c;博主致力于在这里分享关于人工智能&#xff0c;c&#xff0c;Python&#xff0c;爬虫等方面知识的分享。 如果有需要的小伙伴可以关注博主&#xff0c;博主会继续更新的&#xff0c…

OpenCV实战(17)——FAST特征点检测

OpenCV实战&#xff08;17&#xff09;——FAST特征点检测0. 前言1. FAST 特征点检测2. 自适应特征检测3. 完整代码小结系列链接0. 前言 Harris 算子根据两个垂直方向上的强度变化率给出了角点(或更一般地说&#xff0c;兴趣点)的数学定义。但使用这种定义需要计算图像导数&am…

Android 14 新 API:直接监听截屏操作,不用再观察媒体文件了~

截屏可以说是手机设备最常用的功能了&#xff0c;Android 系统非常重视截屏方面的体验&#xff0c;近几年的更新都不忘去优化这方面的体验。 从一开始仅在通知栏提醒已截屏&#xff0c;到 Android 11 支持在左下角生成截屏缩略图供编辑或分享&#xff0c;再到 Android 12 支持…

计算机图形学 | 变换与观察

计算机图形学 | 变换与观察计算机图形学 | 变换与观察6.1 神奇的齐次坐标回顾几何阶段几何变换平移比例旋转对称错切齐次坐标的引入齐次坐标的概念和相关问题基于齐次坐标的变换6.2 三维模型&#xff0c;动起来&#xff01;基本三维变换平移比例旋转对称错切整体比例变换逆变换…

《计算机网络——自顶向下方法》精炼——1.4到1.7

三更灯火五更鸡&#xff0c;努力学习永不止。无惧困难与挑战&#xff0c;砥砺前行向成功。 文章目录引言正文时延排队时延吞吐量协议层次&#xff0c;服务模型&#xff08;重点&#xff09;封装&#xff08;重点&#xff09;网络安全&#xff08;选看&#xff09;恶意软件的分类…

【数据分析与挖掘】数据预处理

目录概述一、数据清洗1.1 缺失值处理1.1.1 拉格朗日插值法1.1.2 牛顿插值法1.2 异常值处理二、数据集成2.1 实体识别2.2 冗余属性识别三、数据变换3.1 简单函数变换3.2 规范化3.3 连续属性离散化3.4 属性构造3.5 小波变换四、数据规约4.1 属性规约4.2 数值规约概述 数据挖掘过…

Spring Boot中使用Redis

目录 1.依赖 2.依赖关系 3.配置 4.RedisTemplate 5.基础操作 6.事务 1.依赖 maven依赖如下&#xff0c;需要说明的是&#xff0c;spring-boot-starter-data-redis里默认是使用lettuce作为redis客户端的驱动&#xff0c;但是lettuce其实用的比较少&#xff0c;我们常用的…