慢吞云雾缓吐愁 发表于 昨天 17:59

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

一、项目现存问题形貌

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

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

结合项目实际情况,设计了一个专用于解决此类并发问题的工具类。该工具类采用了悲观锁方案,利用便捷,以下是不分测试样例与工具类源码。
1、利用测试样例:

    //修改金额
    @Transactional(rollbackFor = Exception.class)
    public void addUserAccountAmount() {
      ConcurrentDataUtils.updateAmount(UserInfo::getAccountAmount, 600, this,Pair.of(UserAccount::getId, 10));
    }
  //判断是否与预期值一致 eg:判断审批状态 是否为待审批,否则应拦截
    @Transactional(rollbackFor = Exception.class)
    public void isEqual() {
      ConcurrentDataUtils.isEqual(Approve::getStatus, 0, this,Pair.of(Approve::getForeignId, 1122334));
    }
    //判断数据是否已存在 eg:同步、保存等场景
    @Transactional(rollbackFor = Exception.class)
    public void isExist() {
      ConcurrentDataUtils.isExist(userInfoService,Pair.of(UserInfo::getIdCard, 1122334),Pair.of(UserInfo::getIsDelete,0));
    }2、工具类源码

https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gifhttps://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gifpackage 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
页: [1]
查看完整版本: 数据并发安全校验处理处罚工具类