Spring事务管理介绍

文章目录

    • Spring事务管理
      • 1 Spring事务简介【重点】
        • 问题导入
        • 1.1 Spring事务作用
        • 1.2 需求和分析
        • 1.3 代码实现
          • 【前置工作】环境准备
          • 【第一步】在业务层接口上添加Spring事务管理
          • 【第二步】设置事务管理器(将事务管理器添加到IOC容器中)
          • 【第三步】开启注解式事务驱动
          • 【第四步】运行测试类,查看结果
      • 2 Spring事务角色【理解】
        • 问题导入
        • 2.1 Spring事务角色
      • 3 Spring事务相关配置
        • 问题导入
        • 3.1 事务配置
        • 3.2 案例:转账业务追加日志
          • 需求和分析
          • 【准备工作】环境整备
          • 【第一步】在AccountServiceImpl中调用logService中添加日志的方法
          • 【第二步】在LogService的log()方法上设置事务的传播行为
          • 【第三步】运行测试类,查看结果
        • 3.3 事务传播行为

Spring事务管理

1 Spring事务简介【重点】

问题导入

Spring提供的事务管理是数据层的事务还是业务层的事务?

1.1 Spring事务作用
  • 事务作用:在数据层保障一系列的数据库操作同成功同失败
  • Spring事务作用:在数据层或**业务层**保障一系列的数据库操作同成功同失败

image-20210801190820853

1.2 需求和分析
  • 需求:实现任意两个账户间转账操作
  • 需求微缩:A账户减钱,B账户加钱
  • 分析:
    ①:数据层提供基础操作,指定账户减钱(outMoney),指定账户加钱(inMoney)
    ②:业务层提供转账操作(transfer),调用减钱与加钱的操作
    ③:提供2个账号和操作金额执行转账操作
    ④:基于Spring整合MyBatis环境搭建上述操作
  • 结果分析:
    ①:程序正常执行时,账户金额A减B加,没有问题
    ②:程序出现异常后,转账失败,但是异常之前操作成功,异常之后操作失败,整体业务失败
1.3 代码实现
【前置工作】环境准备

Spring整合Mybatis相关代码(依赖、JdbcConfig、MybatisConfig、SpringConfig)省略。

public interface AccountDao {@Update("update tbl_account set money = money + #{money} where name = #{name}")void inMoney(@Param("name") String name, @Param("money") Double money);@Update("update tbl_account set money = money - #{money} where name = #{name}")void outMoney(@Param("name") String name, @Param("money") Double money);
}public interface AccountService {/*** 转账操作* @param out 传出方* @param in 转入方* @param money 金额*/public void transfer(String out,String in ,Double money) ;
}@Service
public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountDao accountDao;public void transfer(String out,String in ,Double money) {accountDao.outMoney(out,money);int i = 1/0;accountDao.inMoney(in,money);}
}
【第一步】在业务层接口上添加Spring事务管理
public interface AccountService {//配置当前接口方法具有事务@Transactionalpublic void transfer(String out,String in ,Double money) ;
}

注意事项

  1. Spring注解式事务通常添加在业务层接口中而不会添加到业务层实现类中,降低耦合
  2. 注解式事务可以添加到业务方法上表示当前方法开启事务,也可以添加到接口上表示当前接口所有方法开启事务
【第二步】设置事务管理器(将事务管理器添加到IOC容器中)

说明:可以在JdbcConfig中配置事务管理器

//配置事务管理器,mybatis使用的是jdbc事务
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){DataSourceTransactionManager dtm = new DataSourceTransactionManager();transactionManager.setDataSource(dataSource);return transactionManager;
}

注意事项

  1. 事务管理器要根据实现技术进行选择
  2. MyBatis框架使用的是JDBC事务
【第三步】开启注解式事务驱动
@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
//开启注解式事务驱动
@EnableTransactionManagement
public class SpringConfig {
}
【第四步】运行测试类,查看结果
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTest {@Autowiredprivate AccountService accountService;@Testpublic void testTransfer() throws IOException {accountService.transfer("Tom","Jerry",100D);}
}

2 Spring事务角色【理解】

问题导入

什么是事务管理员,什么是事务协调员?

2.1 Spring事务角色
  • 事务管理员:发起事务方,在Spring中通常指代业务层开启事务的方法
  • 事务协调员:加入事务方,在Spring中通常指代数据层方法,也可以是业务层方法

image-20210801192453227

3 Spring事务相关配置

问题导入

什么样的异常,Spring事务默认是不进行回滚的?

3.1 事务配置

image-20210802151553053

说明:对于RuntimeException类型异常或者Error错误,Spring事务能够进行回滚操作。但是对于编译器异常,Spring事务是不进行回滚的,所以需要使用rollbackFor来设置要回滚的异常。

3.2 案例:转账业务追加日志
需求和分析
  • 需求:实现任意两个账户间转账操作,并对每次转账操作在数据库进行留痕
  • 需求微缩:A账户减钱,B账户加钱,数据库记录日志
  • 分析:
    ①:基于转账操作案例添加日志模块,实现数据库中记录日志
    ②:业务层转账操作(transfer),调用减钱、加钱与记录日志功能
  • 实现效果预期:
    无论转账操作是否成功,均进行转账操作的日志留痕
  • 存在的问题:
    日志的记录与转账操作隶属同一个事务,同成功同失败
  • 实现效果预期改进:
    无论转账操作是否成功,日志必须保留
  • 事务传播行为:事务协调员对事务管理员所携带事务的处理态度

image-20210802153216460

【准备工作】环境整备
USE spring_db;
CREATE TABLE tbl_log(id INT PRIMARY KEY AUTO_INCREMENT,info VARCHAR(255),createDate DATE
);
public interface LogService {//propagation设置事务属性:传播行为设置为当前操作需要新事务@Transactionalvoid log(String out, String in, Double money);
}@Service
public class LogServiceImpl implements LogService {@Autowiredprivate LogDao logDao;public void log(String out,String in,Double money ) {logDao.log("转账操作由"+out+"到"+in+",金额:"+money);}
}public interface LogDao {@Insert("insert into tbl_log (info,createDate) values(#{info},now())")void log(String info);
}
【第一步】在AccountServiceImpl中调用logService中添加日志的方法
@Service
public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountDao accountDao;@Autowiredprivate LogService logService;public void transfer(String out,String in ,Double money) {try{accountDao.outMoney(out,money);int i = 1/0;accountDao.inMoney(in,money);}finally {logService.log(out,in,money);}}
}
【第二步】在LogService的log()方法上设置事务的传播行为
public interface LogService {//propagation设置事务属性:传播行为设置为当前操作需要新事务@Transactional(propagation = Propagation.REQUIRES_NEW)void log(String out, String in, Double money);
}
【第三步】运行测试类,查看结果
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTest {@Autowiredprivate AccountService accountService;@Testpublic void testTransfer() throws IOException {accountService.transfer("Tom","Jerry",50D);}
}
3.3 事务传播行为

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

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

相关文章

智能优化算法应用:基于黄金正弦算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于黄金正弦算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于黄金正弦算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.黄金正弦算法4.实验参数设定5.算法结果6.参考…

Nginx配置反向代理与负载均衡

Nginx配置反向代理与负载均衡 一、代理服务1.正向代理2.反向代理 二、实战场景-反向代理1.修改nginx配置 -> nginx.conf文件2.修改前端路径 三、实战场景-负载均衡1.热备2.轮询3.加权轮询4.ip_hash ​ Nginx (“engine x”) 是一个高性能的HTTP和反向代理服务器,…

10 分钟解释 StyleGAN

一、说明 G在过去的几年里,生成对抗网络一直是生成内容的首选机器学习技术。看似神奇地将随机输入转换为高度详细的输出,它们已在生成图像、生成音乐甚至生成药物方面找到了应用。 StyleGAN是一种真正推动 GAN 最先进技术向前发展的 GAN 类型。当Karras …

力扣题:字符串的反转-11.23

力扣题-11.23 [力扣刷题攻略] Re:从零开始的力扣刷题生活 力扣题1:557. 反转字符串中的单词 III 解题思想:先读取单词,然后将单词进行翻转即可 class Solution(object):def reverseWords(self, s):""":type s…

2024年AMC8美国初中数学竞赛最后一个月复习指南(附资料)

还有一个半月的时间,2024年AMC8(大家默认都直接叫这个比赛的英文名,而不叫中文名美国数学竞赛或美国初中数学竞赛了)就要开始了。 有志于在2024年AMC8的比赛中拿到奖项的孩子已经在“磨拳霍霍”了。那么最后一个半月的时间该如何…

LeetCode刷题---反转链表

个人主页:元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏:http://t.csdnimg.cn/ZxuNL http://t.csdnimg.cn/c9twt 前言:这个专栏主要讲述递归递归、搜索与回溯算法,所以下面题目主要也是这些算法做的 我讲述…

Linux 进程状态

操作系统学科的进程状态 新建态:刚刚创建的进程, 操作系统还未把它加入可执行进程组, 它通常是进程控制块已经创建但还未加载到内存中的新进程。就绪态:进程做好了准备,只要有机会就开始执行。阻塞态:进程在…

Qt+ROS+ubuntu18.04配置教程(带界面)

1. 安装ROS Qt Creator Plug-in 首先安装ROS Qt Creator Plug-in,这其实是一个带有ROS插件的Qt Creator:去下面的网址https://ros-qtc-plugin.readthedocs.io/en/latest/_source/How-to-Install-Users.html#qt-installer-procedure,根据自己…

Java数据结构 之 包装类简单认识泛类

生命不息,奋斗不止 目录 1. 什么是包装类? 1.1 装箱和拆箱 1.2 自动装箱和自动拆箱 2. 什么是泛型 3. 引出泛型 3.1 语法 4 泛型类的使用 4.1 语法 4.2 示例 4.3 类型推导(Type Inference) 5. 裸类型(Raw Type) (了解&#xff09…

IPv6是趋势!如何在Windows上禁用或启用IPv6?有3种简单的方法

IPv6是IPv4的一个更加安全、可扩展和可靠的继任者。然而,这种较新的互联网协议与IPv4不向后兼容,并且大多数VPN服务提供商不支持IPv6协议。 Microsoft不建议用户禁用IPv6或其组件,除非他们需要解决网络问题。但是,如果你计划禁用…

MATLAB实战 | 求水仙花数

循环结构的基本思想是重复,即利用计算机运算速度快以及能进行逻辑控制的特点,重复执行某些语句,以满足大量的计算要求。虽然每次循环执行的语句相同,但语句中一些变量的值是变化的,而且当循环到一定次数或满足条件后能…

阿里云服务器活动:免费试用ECS,轻松搭建WordPress博客平台,送午睡毯及猫超卡

阿里云服务器免费试用3个月 ,搭建WordPress博客平台,还送午睡毯及猫超卡。活动时间截止至12月8日 网址: 阿里云服务器薅羊毛 送午睡毯

mac M系列芯片安装chatGLM3-6b模型

1 环境安装 1.1 mac安装conda. 下载miniconda,并安装 curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh sh Miniconda3-latest-MacOSX-arm64.sh1.2 创建虚拟环境并激活 创建名为chatglm3的虚拟环境,python版本为3.10…

Stream API 方法使用总结

文章目录 1.1、Stream介绍1.2、Stream创建对象(1)empty()方法(2)of()方法(3)Arrays.stream()方法(4)list.stream()方法 1.3、Stream中间方法(1)filter()方法&…

算法设计与实现--贪心篇

贪心算法 贪心算法是一种在每一步选择中都采取当前状态下最优决策的算法,以期望能够通过一系列局部最优的选择达到全局最优。贪心算法的关键是定义好局部最优的选择,并且不回退,即一旦做出了选择,就不能撤销。 一般来说&#xf…

pybind11教程

pybind11教程 文章目录 pybind11教程1. pybind11简介2. cmake使用pybind11教程3. pybind11的历史 1. pybind11简介 项目的GitHub地址为: pybind11 pybind11 是一个轻量级的头文件库,用于在 Python 和 C 之间进行互操作。它允许 C 代码被 Python 调用&am…

C语言-内存分配

内存分配 1. 引入 int nums[10] {0}; //对int len 10; int nums[len] {0}; //错是因为系统的内存分配原则导致的2. 概述 在程序运行时,系统为了 更好的管理进程中的内存,所以有了 内存分配机制。 分配原则: 2.1 静态分配 静态分配原…

CSS——复合选择器、CSS特性、背景属性、显示模式

1、复合选择器 复合选择器:由两个或多个基础选择器,通过不同的方式组合而成。 作用:更准确、更高效的选择目标元素(标签) 1.1 后代选择器 后代选择器:选中某元素的后代元素 选择器写法:父选…

Reactor实战,创建一个简单的单线程Reactor(理解了就相当于理解了多线程的Reactor)

单线程Reactor package org.example.utils.echo.single;import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.*; import java.util.Iterator; import java.util.Set;public class EchoServerReactor implements Runnable{Selector sele…

Android Studio build.gradle获取项目绝对路径

通过这个字段 ${project.rootProject.projectDir}";如项目根build.gradle中: // Top-level build file where you can add configuration options common to all sub-projects/modules.buildscript {repositories {google()mavenCentral()// jcenter() // kee…