数据并发安全校验处理处罚工具类

打印 上一主题 下一主题

主题 898|帖子 898|积分 2694

一、项目现存问题形貌

  当前系统项目中,存在一些并发安全风险问题(固然并发量较小)。特殊是在处理处罚审批状态修改和涉及金额数量的利用,由于缺乏有效的并发控制,可能会导致业务逻辑重复执行和数据不一致。例如 并发场景下,多个线程同时尝试更新同一笔交易状态或金额,这不仅会导致数据不一致,还可能引发更严重的相关业务逻辑错误。
二、一般处理处罚方案概述

乐观锁:
通过在表中添加一个版本号字段来实现,当更新记载时,检查版本号是否与读取时雷同,否则表示数据已被其他事务修改,必要重试。PS:必要现行表增长字段并修改代码支持,改动稍大
悲观锁:
利用数据库提供的锁机制,在查询时即锁定记载。PS:应避免表级锁,查询条件应利用到索引字段。
分布式锁:
对于跨服调用的场景,可以采用redis等缓存技术实现分布式锁,确保在同一时候只有一个服务实例能够对共享资源进行利用。PS:我们的项目开发规则不支持服务层利用redis组件,固开发了这个工具类
事务管理:
公道配置事务隔离级别,确保事务间的可见性服务预期,避免脏读、不可重复读等问题。PS:未便于后期维护,轻易造成事务的未知风险
三、基于现行项目的工具类设计方案

结合项目实际情况,设计了一个专用于解决此类并发问题的工具类。该工具类采用了悲观锁方案,利用便捷,以下是不分测试样例与工具类源码。
1、利用测试样例:
  1.     //修改金额
  2.     @Transactional(rollbackFor = Exception.class)
  3.     public void addUserAccountAmount() {
  4.         ConcurrentDataUtils.updateAmount(UserInfo::getAccountAmount, 600, this,Pair.of(UserAccount::getId, 10));
  5.     }
  6.   //判断是否与预期值一致 eg:判断审批状态 是否为待审批,否则应拦截
  7.     @Transactional(rollbackFor = Exception.class)
  8.     public void isEqual() {
  9.         ConcurrentDataUtils.isEqual(Approve::getStatus, 0, this,Pair.of(Approve::getForeignId, 1122334));
  10.     }
  11.     //判断数据是否已存在 eg:同步、保存等场景
  12.     @Transactional(rollbackFor = Exception.class)
  13.     public void isExist() {
  14.         ConcurrentDataUtils.isExist(userInfoService,Pair.of(UserInfo::getIdCard, 1122334),Pair.of(UserInfo::getIsDelete,0));
  15.     }
复制代码
2、工具类源码

[code]package com.example.dlock_demo.utils;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;import com.baomidou.mybatisplus.core.toolkit.support.SFunction;import com.baomidou.mybatisplus.extension.service.IService;import lombok.extern.slf4j.Slf4j;import org.apache.commons.lang3.tuple.Pair;import java.io.Serializable;import java.lang.invoke.SerializedLambda;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.math.BigDecimal;import java.util.Map;import java.util.Objects;import java.util.Optional;import java.util.concurrent.ConcurrentHashMap;/** * 并发校验、处理处罚数据工具类 * * @author: shf * @date: 2025年02月14日 11:13 */@Slf4jpublic class ConcurrentDataUtils {    private static final String DEFAULT_LAST_JOIN_SQL = "ORDER BY id DESC Limit 1 FOR UPDATE";    private static Map

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

慢吞云雾缓吐愁

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表