springboot + redis 分布式锁在事务提交后再释放锁

目录

常规做法:

常规加锁:

解决办法:


业务描述:新增一个对象,将数据保存到数据库中,且限制最多只能添加15条。

常规做法:

@Transactional(rollbackFor = Exception.class)
public Result add(XXObject object) {
    // 先从数据库中获取总数
    int count = xxService.getCount(xxParam);
    // 达到或超过15条返回提示信息
    if (count >= 15) {
        return Result.fail("已超过上限");    
    }
    // 未超过15条进行新增
    xxService.insert(object);
    return Result.success();
}

这种做法可以在只有一个用户操作的情况下,实现限制15条。

但是如果是多个用户同时添加,或者稍微极端一些,进行并发压测都会出现超过15条上限的问题

这时就需要对业务代码进行加锁,

常规加锁:

        代码如下:



@Transactional(rollbackFor = Exception.class)
public Result add(XXObject object) {
    // 锁的名称
    String redisKey = "lockName";
    // 上锁
    String lockValue = lock.lock(redisKey, 5000, 5000);
    try {
        // 先从数据库中获取总数
        int count = xxService.getCount(xxParam);
        // 达到或超过15条返回提示信息
        if (count >= 15) {
            return Result.fail("已超过上限");    
        }
        // 未超过15条进行新增
        xxService.insert(object);
        return Result.success();
    } catch (Exception e) {
        return Result.fail("添加失败,请稍后重试");
    } finally {
        // 解锁
        lock.unlock(redisKey, lockValue);
    }
}

虽然加上了锁,但是还有一个问题,就是锁释放后,事务才进行提交,这就导致锁先释放了,别的线程拿到锁读取到旧的数据,然后上一个事务才提交,导致多插入了数据。

解决办法:

        1、去掉事务注解,仅限业务中只有单表插入,避免多表插入发生异常时,没有事务无法回滚的问题。

        2、在事务提交后再释放锁,代码如下:

public Result add(XXObject object) {
    // 锁的名称
    String redisKey = "lockName";
    // 上锁
    String lockValue = lock.lock(redisKey, 5000, 5000);
    try {
        // 通过spring 上下文获取当前service对象,然后执行方法,且开启了事务
        XXService xxService = SpringContextUtil.getBean(QiStrategyService.class);
        return xxService.add(object);
    } catch (Exception e) {
        return Result.fail("添加失败,请稍后重试");
    } finally {
        // 解锁
        lock.unlock(redisKey, lockValue);
    }
}

@Transactional(rollbackFor = Exception.class)
public Result add(XXObject object) {
    // 先从数据库中获取总数
    int count = xxService.getCount(xxParam);
    // 达到或超过15条返回提示信息
    if (count >= 15) {
        return Result.fail("已超过上限");    
    }
    // 未超过15条进行新增
    xxService.insert(object);
    return Result.success();
}

还有一种解决方法,可以利用spring 切面进行实现,定一一个注解,然后实现注解的处理器,在处理器中控制事务的开启、提交和回滚,减少加锁和释放锁的代码重复使用。(有时间再补上这块的代码)

如有问题,欢迎指正,感谢!撒花!

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

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

相关文章

ipv4Bypass:一款基于IPv6实现的IPv4安全绕过与渗透测试工具

关于ipv4Bypass ipv4Bypass是一款基于IPv6实现的安全绕过与渗透测试工具,该工具专为红队研究人员设计,可以帮助广大研究人员通过IPv6绕过目标安全策略,以此来检测安全检测机制的健壮性。 20世纪90年代是互联网爆炸性发展时期,随着…

Sourcetree安装使用(补个笔记)

Sourcetree介绍 Sourcetree是一款免费的Git图形化客户端,它由Atlassian开发,提供了跨平台的支持,可运行在Windows和Mac操作系统上。Sourcetree可以让开发者更方便地使用Git来管理代码,不需要在命令行中输入复杂的Git命令&#xf…

【QTM中文教程】02:Quick Terrain Reader介绍、下载与安装

文章目录 一、Quick Terrain Reader简介二、Quick Terrain Reader特点和功能三、Quick Terrain Reader下载与安装一、Quick Terrain Reader简介 Quick Terrain Reader(QTR)是一款免费的软件工具,用于查看和分析地形数据。它是Quick Terrain Modeler(QTM)的轻量级版本,专…

houdini 节点

bend 【m f b 】 polyexpand2d copytopoint polyframe group range

Uniapp百度AI人脸识别证件照微信小程序源码

百度AI人脸识别证件照微信小程序源码,Uniapp开发的一套证件照制作的微信小程序源码,带视频激励广告主。 使用教程: 1、hbuildx 打开项目(仅尝试过hbuildx,cli需要自己尝试) 2、修改代码的appid 3、进入…

移除离群点------PCL

statisticalOutlierRemoval滤波器移除离群点 /// <summary> /// 使用statisticalOutlierRemoval滤波器移除离群点 /// </summary> /// <param name"cloud">被过滤的点云</param> /// <param name"meank"></param> //…

如何将jpeg改为jpg格式?jpeg转换成jpg的三种方法

在我们的日常生活和工作中&#xff0c;经常需要进行图片格式转换&#xff0c;比如在许多社交平台中&#xff0c;我们可能需要将jpeg格式的图片转换为更常见的jpg格式&#xff0c;以便在不同设备或平台上更好地使用和查看&#xff0c;也更方便地分享和存储这些图片&#xff0c;而…

CHI中observe响应和order响应的区别

在CHI协议中&#xff0c;每个请求可以生成一个或多个响应&#xff0c;不同响应表示Completer完成不同的操作之后&#xff0c;返回给requestor的通知。Requestor收到响应之后&#xff0c;根据响应类型来判断下一步需要做什么。 1. Observe响应 Observe响应确定一个transaction相…

java线程间同步----wait、notify、synchronized

一、wait、notify wait、notify 是java 根级父类Obeject 中定义得两个方法&#xff0c;其相关作用如下&#xff1a; object.wait()&#xff1a;执行该语句&#xff0c;会让获取了该object对象锁得线程进入WAIT状态&#xff0c;并释放该object对象锁&#xff1b; object.notify…

同旺科技 USB TO SPI / I2C适配器读写24LC256--字节写

所需设备&#xff1a; 1、USB 转 SPI I2C 适配器&#xff1b;内附链接 2、24LC256芯片 适应于同旺科技 USB TO SPI / I2C适配器升级版、专业版&#xff1b; 00地址写入一个字节数据AA&#xff0c;并读回验证&#xff1b; 单字节写时序&#xff1a; 读字节时序&#xff1a; …

OpenCV——透视变换

前言 ​ 需求&#xff1a; 将一个梯形变为需要的图形&#xff0c;后续需要持续进行映射。让整张图像的所有点位都按照这样的映射关系进行映射。 正文 一、透视变换相关介绍 从名称中可以清楚地看出&#xff0c;透视变换研究是坐标变化之间的关系。这种类型的转换不保留信息…

数据采集技术综合项目实战3(网络爬虫+数据预处理+数据可视化)附带详细步骤说明,干货满满

项目介绍及需求&#xff1a; 本项目主要是通过对b站电影弹幕进行采集并分析。1.获得弹幕高频词生成符合该电影特征、主题、角色等相关字段的词云图&#xff0c;通过词云图的方式对某部电影主题具体化。2.获取用户年内评论发布时间观生成时间的折线图&#xff0c;以便从侧面观察…

HarmonyOS-静态库(SDK)的创建和使用

文章目录 一、静态库&#xff08;SDK&#xff09;二、创建静态库1.新建静态库模块2. 开发静态库内容3. 编译静态库 三、使用静态库1. 配置项目依赖2. 在应用中使用静态库3. 注意事项 四、打包错误1. library引用本地har包错误 一、静态库&#xff08;SDK&#xff09; 在Harmon…

【35分钟掌握金融风控策略6】决策树风控策略开发

目录 ​编辑 决策树 决策树原理 决策树生成 特征选择 决策树生成 决策树剪枝 决策树 决策树&#xff08;Decision Tree&#xff09;是一种强大的分类和预测方法&#xff0c;因其实践起来比较简单且具有较好的解释性&#xff0c;所以在金融风控领域应用广泛。决策树也是…

如何快速提高阿里国际、Shopee和速卖通产品的曝光率?

当卖家完成产品上传后&#xff0c;他们还能做些什么来进一步提升产品的曝光量呢&#xff1f;产品的曝光量无疑对店铺的销量具有显著影响&#xff0c;那么&#xff0c;如何有效地提升产品曝光量呢&#xff1f;又有哪些快速且实用的方法呢&#xff1f;今天&#xff0c;我们就来深…

【力扣 Hot100 | 第五天】4.20(回文链表)

1.回文链表 1.1题目 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例一&#xff1a; 输入&#xff1a;head [1,2,2,1] 输出&#xff1a;true示例二&#xff1a; 输入…

智慧城市标准化白皮书(2022版)发布

2022年7月25日&#xff0c;国家智慧城市标准化总体组2022年度全体会议召开期间&#xff0c;《智慧城市标准化白皮书&#xff08;2022版&#xff09;》正式发布。 城市作为一个复杂巨系统&#xff0c;是多元主体融合及多元活动集聚的复杂综合体。城市的运行发展关联 到发展、治…

康耐视visionpro-Cog2DSymbolTool操作操作工具详细说明

Cog2 DSymbolToolI功能说明&#xff1a; 二维码读取工具 Cog2 DSymbolTool操作说明&#xff1a; ①.打开工具栏&#xff0c;双击或点击鼠标拖拽添加Cog2DSymbolTool工具 ②.添加输入图像&#xff0c;右键“链接到”或以连线拖拽的方式选择相应输入图像。 ③.代码系统&#x…

Pytest精通指南(22)钩子函数-重复执行(pytest-repeat)

文章目录 前言应用场景插件安装参数分析使用方式一&#xff1a;命令行使用方式二&#xff1a;配置文件使用方式三&#xff1a;装饰器 前言 pytest框架中的**重复测试&#xff08;pytest-repeat&#xff09;**插件的用途是允许在运行测试用例时进行多次循环&#xff0c;以更全面…

2024年开通最新版云开发cms步骤,开始开发微信小程序前的准备工作,认真看完奥!

小程序官方有改版了&#xff0c;搞得石头哥不得不紧急的再新出一版&#xff0c;教大家开通最新版的cms网页管理后台 一&#xff0c;技术选型和技术点 1&#xff0c;小程序前端 wxml css JavaScript MINA原生小程序框架 2&#xff0c;数据库 云开发 云数据库 云…
最新文章