SpringBoot中使用redis事务

news2024/9/24 11:33:17

本文基于SpringBoot 2.X

事务在关系型数据库的开发中经常用到,其实非关系型数据库,比如redis也有对事务的支持,本文主要探讨在SpringBoot中如何使用redis事务。

事务的相关介绍可以参考:

0、起因

在一次线上事故中,我们定位到redis的使用存在大value,超过了dubbo的最大数据量限制,于是紧急将这个大的对象value拆分成单个的string value。

为了保持数据库和redis双写一致,在对数据库进行更新,删除,插入操作时,要从redis删除指定的key。

一切都是使用redis的常规操作,但雷就埋在其中一个数据库的update方法里,这个方法上开启了事务@Transactional,导致里面的删除redis key操作也加入了事务。

上线后出现报错:

这个报错明确指出,集群模式的redis不支持事务。集群不支持事务的原因可参考此文:Is there any Redis client (Java prefered) which supports transactions on Redis cluster?

1、Spring中的事务

所有数据访问技术都有事务机制,这些技术提供了API来开启事务、提交事务完成数据操作, 或者在发生错误的时候回滚数据。

Spring采用统一的机制来处理不同的数据访问技术的事务, Spring的事务提供一个PlatformTransactionManager的接口,不同的数据访问技术使用不同的接口实现。

数据访问技术实现
JDBCDataSourceTransactionManager
JPAJPATransactionManager
HibernateHibernateTransactionManager
JDOJDOTransactionManager
分布式事务JtaTransactionManager
  • 在SpringBoot中开启事务非常简单,只需要在方法或类上使用注解@Transactional即可。
  • Spring官方文档中还要求使用@EnableTransactionManagement 开启事务,但SpringBoot通过自动配置已经帮我们做了,所以SpringBoot中不用写该注解

@Transactional注解的几个常用属性

  • propagation

事务的传播机制,主要有以下几种,默认是REQUIRED

  1. REQUIRED - 方法A调用时候没有事务新建一个事务,在方法A中调用方法B,将使用相同的事务,如果方法B发生异常需要回滚,整个事务回滚。
     

  2. REQUIRES_NEW - 方法A调用方法B时,无论是否存在事务都开启一个新事务,这样B方法异常不会导致A的数据回滚。
     

  3. NESTED - 和REQUIRES_NEW类似,但是只支持JDBC,不支持JPA或Hibernate

  4. SUPPORTS - 方法调用时有事务就用事务,没事务就不用事务

  5. NOT_SUPPORTED - 强制方法不在事务中执行,若有事务,在方法调用到结束阶段先挂起事务。

  6. NEVER - 强制不能有事务,若有事务就抛出异常

  7. MANDATORY - 强制必须有事务,如果没有事务就抛出异常

  • rollbackFor

指定哪些异常可以导致事务回滚,默认是Throwable的子类

  • noRollbackFor

执行哪些异常不可用引起事务回滚,默认是Throwable的子类

2、@Transactional事务失效的情况

  1. 只对public方法生效。默认的protected和private方法上写上@Transactional不会报错,但该方法上的事务不生效,官方原文:Method visibility and @Transactional;
  2. 默认情况(只写@Transactional不填写rollbackFor参数)下此注解会对unchecked异常进行回滚,对checked异常不回滚;
  3. 类内部未开启事务的方法调用开启事务的方法

针对3,引用丁雪丰的《Spring全家桶》视频中的解释:

Spring的声明式事务本质上是通过AOP来增强了类的功能

Spring的AOP本质上就是为类做了一个代理

看似在调用自己写的类,实际用的是增强后的代理类

下图描述了方法被事务代理时的流程,来源:Spring AOP
 

3、SpringBoot整合Redis事务实践

下面我们搭建一个最简单的SpringBoot整合redis的工程用代码来验证redis事务

  • SpringBoot整合Redis

SpringBoot整合redis使用的是spring-boot-starter-data-redis,redis事务依赖于jdbc的事务管理,所以还需要引入jdbc

pom相关引入:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
	<groupId>com.h2database</groupId>
	<artifactId>h2</artifactId>
	<scope>runtime</scope>
</dependency>
  • 开启Redis事务

编写redis配置类,开启redis事务,配置事务管理

@Configuration
public class RedisConfig {
    @Bean
    public StringRedisTemplate StringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        /**
         * description 开启redis事务(仅支持单机,不支持cluster)
         **/
        template.setEnableTransactionSupport(true);
        return template;
    }
    /**
     * description 配置事务管理器
     **/
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }
}
  • 代码验证

针对本文讨论,设计了四个验证方法,可自行验证

/**
 * description 不带事务set
 * return java.lang.String
 * author 郑晓龙
 * createTime 2019/12/12 16:36
 **/
@GetMapping("put")
public void put(String key, String value) {
	redisService.put(key, value);
}
/**
 * description 带事务set
 * return java.lang.String
 * author 郑晓龙
 * createTime 2019/12/12 16:36
 **/
@GetMapping("putWithTx")
public void putWithTx(String key, String value) {
	redisService.putWithTx(key, value);
}
/**
 * description 调用带事务方法不生效的情况
 * return java.lang.String
 * author 郑晓龙
 * createTime 2019/12/12 16:36
 **/
@GetMapping("invokeWithPutTx")
public void invokeWithPutTx(String key, String value) {
	redisService.invokePutWithTx(key, value);
}
/**
 * description 调用带事务方法生效的情况
 * return java.lang.String
 * author 郑晓龙
 * createTime 2019/12/12 16:36
 **/
@GetMapping("invokeWithPutTx2")
public void invokeWithPutTx2(String key, String value) {
	redisService.invokePutWithTx2(key, value);
}

4、总结:

  • redis事务只支持单机,不支持cluster
  • 需要开启事务时,只需要在对应的方法或类上使用@Transactional注解即可,SpringBoot自动开启了@EnableTransactionManagement
  • 需要注意事务不生效的几种情况
  • redis事务依赖于jdbc的事务管理

5、示例代码及参考:

示例代码: redis-transaction

  1. Transaction Management
  2. Transaction Propagation
  3. Transactional Support
  4. 《Spring全家桶》丁雪丰

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

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

相关文章

与春相拥,在职读研邂逅中国人民大学与加拿大女王大学金融硕士项目何其有幸

工作几年后的你是否有冒出在职读研的想法&#xff1f;或许你为此纠结了一段时间&#xff0c;在职读研要考虑到的因素众多&#xff0c;年龄、精力分配等&#xff0c;工作几年&#xff0c;经历了职场的磨练&#xff0c;更能知道自己家想要的是什么&#xff0c;对于是否读研会有一…

红海云签约长久数科,引领汽车流通行业人力资源数字化创新

上海铂中数字科技有限公司&#xff08;以下简称“长久数科”&#xff09;是国内领先的数字化汽车供应链服务企业&#xff0c;致力于通过整合客户资源、技术资源、产业链配套资源以及地面服务资源&#xff0c;打造一站式服务的汽车生态大数据SaaS平台。 近日&#xff0c;长久数…

编译原理陈火旺第三版第六章课后题答案

下面的答案仅供参考&#xff01; 1.按照表6.1所示的属性文法&#xff0c;构造表达式(4*71) *2的附注语法树。 答&#xff1a; 首先考虑最底最左边的内部结点,它对应于产生式F→digit,相应的语义规则为F. val: digit.lexval,由于这个结点的子结点digit的属性digit . lexval的…

一文彻底理解Java 17中的新特性密封类

密封类的作用 在面向对象语言中&#xff0c;我们可以通过继承&#xff08;extend&#xff09;来实现类的能力复用、扩展与增强。但有的时候&#xff0c;有些能力我们不希望被继承了去做一些不可预知的扩展。所以&#xff0c;我们需要对继承关系有一些限制的控制手段。而密封类…

android framework-ActivityManagerService(AMS)上

一、SystemServer android-10.0.0_r41\frameworks\base\services\java\com\android\server\SystemServer.java 1.1、startOtherService AMS初始化完成后&#xff0c;会调用systemReady方法。 mActivityManagerService.systemReady(() -> {Slog.i(TAG, "Making service…

springboot +flowable,简单实现工作流基础功能的demo例子

一.简介 对于flowable是什么以及关于此框架的具体信息可以参看此项目的官方文档&#xff1a;https://www.flowable.org/docs/userguide/index.html Flowable is a light-weight business process engine written in Java.这是官网文档对此框架的完美解释&#xff1a;Flowable…

NetApp AFF C 系列全闪存存储解决方案

NetApp AFF C 系列: “C”代表“酷炫”(Cool) 采用最新的容量闪存技术&#xff0c;辅以若干一流的智能技术&#xff0c;您将获得一个经济实惠的闪存解决方案&#xff0c;它重新定义了安全性、可扩展性和可持续性。 为什么选择 AFF C 系列的容量闪存解决方案&#xff1f; 实现…

jmeter获取图片验证码-解密图片并识别

说明&#xff1a; 关于图片验证码的处理方式有三种方法&#xff1a;一是让开发屏蔽验证码&#xff0c;二是让开发后端指定一个万能验证码&#xff0c;三是使用OCR工具进行图片验证码的解密及识别&#xff0c;推荐使用前两种方法最省事&#xff1b; OCRServer工具识别图片验证码…

Netty核心源码分析(二),Netty的Server端接收请求过程源码分析

文章目录 系列文章目录一、连接请求接受过程源码分析1、事件的值2、processSelectedKeys获取事件&#xff08;1&#xff09;doReadMessages方法&#xff08;2&#xff09;pipeline的fireChannelRead方法&#xff08;3&#xff09;ServerBootstrapAcceptor的channelRead方法 3、…

关于数据挖掘和数据集成?

按照数据的生命周期&#xff0c;我们通常将大数据技术分为数据集成、数据存储、批流处理、数据查询与分析、数据调度与编排、数据开发、BI 7 个部分。 可以看到数据集成在数据生命周期最前面的位置&#xff0c;它负责将多个来自不同数据源的数据聚合存放在一个数据存储中&…

分布式任务调度框架Power-Job

分布式任务调度框架的由来及对比 在大型业务业务系统中&#xff0c;不可避免会出现一些需要定时执行需求的场景&#xff0c;例如定时同步数据&#xff0c;定时清洗数据&#xff0c;定时生成报表&#xff0c;大量机器一同执行某个任务&#xff0c;甚至有些需要分布式处理的任务…

中继器+js组件化GIS地图

虽然可以使用JavaScript注入的方式将GIS地图嵌入Axure&#xff0c;但每次使用地图都需要重复嵌入并修改代码&#xff0c;不太方便。那么&#xff0c;能不能实现组件化呢&#xff1f;我们可以使用中继器&#xff08;repeater&#xff09;将常用的地图参数提取出来&#xff0c;通…

力扣题库刷题笔记406-根据身高重建队列

1、题目如下&#xff1a; 2、个人Python代码实现 这里需要单独备注一下截图中第21行代码&#xff1a; 上图可以看到&#xff0c;已经对[5, 2]等元素进行了遍历循环&#xff0c;且[5, 2]左侧确实只存在[7, 0][6, 1]两个元素身高高于他&#xff0c;但是继续[5,0]循环完成后&#…

@Async异步线程:Spring 自带的异步解决方案

前言 在项目应用中&#xff0c;使用MQ异步调用来实现系统性能优化&#xff0c;完成服务间数据同步是常用的技术手段。如果是在同一台服务器内部&#xff0c;不涉及到分布式系统&#xff0c;单纯的想实现部分业务的异步执行&#xff0c;这里介绍一个更简单的异步方法调用。 对于…

FreeRTOS - 计数信号量

一.任务功能 1、修改按键功能&#xff0c;模拟停车位出入功能 2、当按键按下 获取车位 3、当按键抬起 释放车位 二.API接口 函数原型SemaphoreHandle_t xSemaphoreCreateCounting( ①UBaseType_t uxMaxCount,②UBaseType_t uxInitialCount );功能概述创建计数信号量&#xff0c…

详解空气质量API 使用

引言 空气污染是当今世界面临的一大环境问题&#xff0c;而空气质量监测数据是制定环境政策和公众健康计划的重要依据。通过提供空气质量查询 API&#xff0c;开发人员可以方便地获取中国境内多个城市的空气质量数据&#xff0c;从而更好地监测和管理空气质量。 本文将介绍的…

Redis入门学习笔记【一】

目录 一、redis是什么 二、Redis数据结构 2.1 Redis 的五种基本数据类型 2.1.1String&#xff08;字符串&#xff09; 2.1.2字符串列表&#xff08;lists&#xff09; 2.1.3字符串集合&#xff08;sets&#xff09; 2.1.5哈希&#xff08;hashes&#xff09; 2.2 Red…

设计模式详解-软件设计(五十六)

原创 真题详解(UML图)-软件设计&#xff08;五十五)https://blog.csdn.net/ke1ying/article/details/130311994 创建型、结构型、行为型 抽象工厂&#xff08;Abstruct Factory&#xff09; 提供一个创建系列相关或相互依赖的接口&#xff0c;无须指定他们具体的类。 适用于&…

07-Node.js—包管理工具

目录 1、概念介绍1.1 包是什么1.2 包管理工具1.3 常用的包管理工具 2、npm2.1 npm 的安装2.2 npm 基本使用2.2.1 初始化2.2.2 搜索包2.2.3 下载安装包2.2.4 require 导入 npm 包基本流程 2.3 生产环境与开发环境2.4 生产依赖与开发依赖2.5 全局安装2.5.1 修改 windows 执行策略…

CorelDRAW 2023版本更新内容及安装详细教程

这里是CorelDRAW 2023版本更新内容及安装详细教程: CorelDRAW 2023是最新更新版本,在界面和功能上做了较大提升与优化: 1. 简洁界面:采用全新设计界面,简约而不简单。菜单和工具栏进行了整合与重组,更加直观。拥有自动标记和提示,易于上手使用。 2. 全新工作空间:提供“轻量…