Spring Boot 3 高并发事务与分布式事务企业级完整解决方案

Spring Boot 3 高并发事务与分布式事务企业级完整解决方案

写这个因为,是有个接口没做事务兜底机制。

从单体高并发 → 分布式高并发 · 全链路异常兜底 · 企业级生产就绪


文档说明

  • 适用版本:Spring Boot 3.2+,Java 17+,JPA / MyBatis / R2DBC 均支持
  • 目标读者:后端架构师、高级开发工程师、SRE
  • 核心价值 :覆盖 单体高并发优化 → 分布式事务选型 → 异常兜底 → 可观测性 → 容灾对账 全生命周期
  • 企业级标准:满足金融、电商、支付等强一致性与高可用场景

一、整体演进路径与选型原则

架构阶段 并发规模 数据一致性要求 推荐方案 是否需分布式事务
单体应用(高并发) 1k~10k TPS 强一致(本地 ACID) 本地事务 + 乐观锁/分段锁 + 异步解耦 ❌ 否
微服务初期(最终一致) 10k+ TPS 最终一致(秒级容忍) Outbox 模式 + MQ + 幂等消费 ✅ 轻量级
强一致场景(金融/支付) 高并发 + 强一致 强一致(毫秒级) Seata TCC / Saga ✅ 强一致性
超大规模(跨境/多云) 100k+ TPS 最终一致 + 对账兜底 Event Sourcing + CDC + 补偿平台 ✅ 最终一致

企业共识

  • 90% 场景用"最终一致性 + 对账"
  • 仅关键资金链路用 TCC
  • 绝不使用 XA(性能差、运维难)

二、单体高并发事务优化方案(企业级)

2.1 核心问题

  • 数据库行锁/间隙锁竞争
  • 事务持有时间过长导致连接池耗尽
  • 死锁频发(尤其 MySQL InnoDB)
  • CPU 飙升、TPS 下降

2.2 企业级解决方案

✅ 方案 A:细粒度事务 + 异步解耦(推荐)
java 复制代码
@Service
public class OrderService {

    @Autowired
    private ApplicationEventPublisher eventPublisher;

    // 主流程:极简事务(<50ms)
    @Transactional(timeout = 10)
    public Order createOrder(OrderRequest request) {
        Order order = new Order(request);
        order.setStatus("CREATED");
        order = orderRepo.save(); // 快速提交

        // 发布领域事件(异步处理非核心逻辑)
        eventPublisher.publishEvent(new OrderCreatedEvent(order.getId(), request.getItems()));
        return order;
    }
}

// 异步监听器(独立事务)
@Component
@RequiredArgsConstructor
public class InventoryEventListener {
    private final InventoryService inventoryService;

    @Transactional
    @EventListener
    public void handleOrderCreated(OrderCreatedEvent event) {
        try {
            inventoryService.reduceStock(event.orderId(), event.items());
        } catch (Exception e) {
            // 记录失败,由补偿任务重试
            compensationService.recordFailure("INVENTORY_REDUCE", event.orderId(), e);
            throw e; // 触发重试机制
        }
    }
}

优势 :主流程快、锁持有时间短、系统吞吐提升 3~5 倍
注意@EventListener 默认同步,需配置 TaskExecutor 实现异步

✅ 方案 B:乐观锁(高并发更新)
java 复制代码
@Entity
public class Account {
    @Version
    private Long version; // JPA 乐观锁字段
    private BigDecimal balance;
}

@Service
@Transactional
public class AccountService {
    public void transfer(Long fromId, Long toId, BigDecimal amount) {
        int retry = 0;
        while (retry < 3) {
            try {
                Account from = accountRepo.findById(fromId).orElseThrow();
                Account to = accountRepo.findById(toId).orElseThrow();

                from.setBalance(from.getBalance().subtract(amount));
                to.setBalance(to.getBalance().add(amount));

                accountRepo.save(from);
                accountRepo.save(to);
                return; // 成功退出
            } catch (OptimisticLockException e) {
                retry++;
                if (retry >= 3) throw new ServiceException("并发冲突,请重试", e);
                Thread.sleep(10 * retry); // 指数退避
            }
        }
    }
}

适用 :余额变动、积分增减等低冲突场景
不适用:秒杀库存(高频冲突)

✅ 方案 C:分段锁 + 库存预热(秒杀场景)
java 复制代码
@Component
public class SeckillInventoryService {
    private static final int SEGMENT_COUNT = 16;
    private final Object[] locks = new Object[SEGMENT_COUNT];
    private final Map<String, AtomicInteger[]> inventorySegments = new ConcurrentHashMap<>();

    public SeckillInventoryService() {
        for (int i = 0; i < SEGMENT_COUNT; i++) {
            locks[i] = new Object();
        }
    }

    public boolean trySeckill(String skuId, Long userId) {
        int segment = Math.abs(userId.hashCode()) % SEGMENT_COUNT;
        synchronized (locks[segment]) {
            AtomicInteger[] segments = inventorySegments.computeIfAbsent(skuId, k -> 
                IntStream.range(0, SEGMENT_COUNT).mapToObj(i -> new AtomicInteger(getTotalStock(k) / SEGMENT_COUNT)).toArray(AtomicInteger[]::new)
            );

            if (segments[segment].get() > 0) {
                segments[segment].decrementAndGet();
                return true;
            }
        }
        return false;
    }

    // 定时同步到 DB(每秒一次)
    @Scheduled(fixedRate = 1000)
    public void syncToDatabase() {
        // 批量更新 DB 库存
    }
}

效果:将全局锁 → 16 个局部锁,并发能力提升 10 倍+


三、分布式高并发事务方案(企业级)

3.1 方案选型矩阵

方案 一致性 性能 开发成本 运维成本 适用场景
Outbox + MQ(最终一致) 最终一致 ⭐⭐⭐⭐⭐ ⭐⭐ 电商下单、社交互动
Seata TCC 强一致 ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ 支付转账、积分兑换
Saga(编排式) 最终一致 ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐ 订单履约、审批流
XA 强一致 ⭐⭐ ⭐⭐⭐⭐ 遗留系统(禁用)

企业推荐

  • 默认选择 Outbox + MQ
  • 仅当业务无法容忍任何不一致时用 TCC

3.2 方案一:Outbox 模式 + MQ(最终一致性 · 企业首选)

架构图
  1. 本地事务 2. 定时任务 3. 异步投递 4. 幂等消费 5. 成功 6. 失败 7. 人工补偿 8. 每日跑批 订单服务
    B
    RabbitMQ/Kafka
    库存服务
    扣库存
    ACK
    死信队列
    补偿管理平台
    对账系统
    核对订单 vs 库存
关键实现
(1)Outbox 消息表(与业务同库)
sql 复制代码
CREATE TABLE outbox_message (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    event_type VARCHAR(100) NOT NULL,
    payload JSON NOT NULL,
    business_key VARCHAR(100) NOT NULL, -- 如 order_id
    status ENUM('PENDING', 'SENT') DEFAULT 'PENDING',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    sent_at DATETIME NULL,
    INDEX idx_status_created (status, created_at),
    UNIQUE KEY uk_biz_event (business_key, event_type)
);
(2)可靠消息发送(带重试)
java 复制代码
@Service
@RequiredArgsConstructor
public class OutboxMessageService {
    private final OutboxMessageRepository outboxRepo;
    private final MqProducer mqProducer;

    @Scheduled(fixedDelay = 2000)
    @Transactional
    public void sendPendingMessages() {
        List<OutboxMessage> messages = outboxRepo.findPendingBefore(Instant.now().minusSeconds(10));
        for (OutboxMessage msg : messages) {
            try {
                mqProducer.send(msg.getEventType(), msg.getPayload());
                msg.markAsSent();
                outboxRepo.save(msg);
            } catch (Exception e) {
                log.warn("消息发送失败,稍后重试: {}", msg.getId(), e);
                // 不抛异常,避免事务回滚
            }
        }
    }

    // 业务方法中保存消息
    public void saveMessage(String eventType, String payload, String businessKey) {
        outboxRepo.save(new OutboxMessage(eventType, payload, businessKey));
    }
}
(3)幂等消费(双保险)
java 复制代码
@RabbitListener(queues = "inventory.queue")
public void consume(InventoryEvent event) {
    String idempotentKey = event.getOrderId() + ":DECREASE";

    // 1. Redis 快速去重
    if (redis.hasKey("IDEMPOTENT:" + idempotentKey)) {
        return;
    }

    // 2. DB 唯一索引兜底
    try {
        idempotentLogService.log(idempotentKey); // 唯一索引 INSERT
        inventoryService.decrease(event.getItems());
    } catch (DuplicateKeyException e) {
        log.info("重复消费,跳过: {}", idempotentKey);
        return;
    } catch (Exception e) {
        // 系统异常:MQ 自动重试(最多5次)
        throw new AmqpRejectAndDontRequeueException(e);
    }
}
(4)兜底:补偿平台 + 对账
  • 补偿平台:提供 UI 查看失败事件、手动重试、跳过、数据修正

  • 对账任务

    java 复制代码
    @Scheduled(cron = "0 0 2 * * ?") // 每日凌晨2点
    public void dailyReconciliation() {
        List<Order> paidOrders = orderRepo.findPaidYesterday();
        for (Order order : paidOrders) {
            if (!inventoryService.isAllocated(order.getId())) {
                alarmService.send("库存未分配", order.getId());
                // 自动触发补偿 or 人工介入
            }
        }
    }

3.3 方案二:Seata TCC(强一致性 · 金融级)

架构图
复制代码
[Client] 
   │
   ▼
[Order Service] → @GlobalTransactional
   │
   ├──→ [Inventory Service] → @LocalTCC (Try/Confirm/Cancel)
   └──→ [Account Service] → @LocalTCC (Try/Confirm/Cancel)
   │
   ▼
[Seata Server (TC)] ← 协调全局事务
关键代码
(1)Seata 配置(application.yml)
yaml 复制代码
seata:
  enabled: true
  application-id: ${spring.application.name}
  tx-service-group: my_tx_group
  service:
    vgroup-mapping:
      my_tx_group: default
  registry:
    type: nacos
    nacos:
      server-addr: ${NACOS_SERVER}
  config:
    type: nacos
(2)TCC 接口实现
java 复制代码
@LocalTCC
public interface InventoryTccService {
    @TwoPhaseBusinessAction(name = "decreaseInventory", commitMethod = "confirm", rollbackMethod = "cancel")
    boolean prepareDecrease(BusinessActionContext ctx, Long orderId, List<Item> items);

    boolean confirm(BusinessActionContext ctx);
    boolean cancel(BusinessActionContext ctx);
}

@Component
public class InventoryTccServiceImpl implements InventoryTccService {

    @Override
    public boolean prepareDecrease(BusinessActionContext ctx, Long orderId, List<Item> items) {
        // Try: 冻结库存(必须幂等)
        return inventoryRepo.freezeIfNotExists(orderId, items);
    }

    @Override
    public boolean confirm(BusinessActionContext ctx) {
        try {
            inventoryRepo.confirmFrozen(ctx.getActionContext("orderId"));
            return true;
        } catch (Exception e) {
            log.error("Confirm 失败,需人工介入!", e);
            alarmService.sendCritical("TCC Confirm 失败", ctx.getXid());
            return false; // 不会自动重试!
        }
    }

    @Override
    public boolean cancel(BusinessActionContext ctx) {
        try {
            inventoryRepo.releaseFrozen(ctx.getActionContext("orderId"));
            return true;
        } catch (Exception e) {
            // Cancel 失败是严重事故!
            alarmService.sendCritical("TCC Cancel 失败", ctx.getXid());
            return false;
        }
    }
}
(3)全局事务调用
java 复制代码
@Service
public class OrderService {
    @GlobalTransactional(timeoutMills = 30000)
    public void createOrderWithTcc(OrderRequest request) {
        orderRepo.create(request); // 本地 RM
        inventoryService.prepareDecrease(request.getItems()); // 远程 TCC
        accountService.prepareFreeze(request.getAmount());     // 远程 TCC
    }
}

TCC 注意事项

  • prepare 必须幂等
  • confirm/cancel 失败需告警 + 人工处理
  • 全局事务日志(undo_log)需定期归档

第四章:事务异常兜底与企业级容灾方案(完整重写)

目标 :确保在任何异常场景下,系统具备自动恢复能力人工干预通道数据最终一致性保障
适用范围 :Spring Boot 3 单体高并发 & 分布式微服务架构
核心理念"事务可能失败,但业务不能中断"


4.1 异常分类与响应策略(企业级标准)

4.1.1 异常类型定义

异常大类 具体场景 是否可自动恢复 事务影响
业务异常 余额不足、库存不足、参数校验失败 ❌ 不可恢复(需用户修正) 立即回滚,不触发重试
系统异常 NPE、数据库连接失败、序列化错误 ✅ 可恢复(重试后可能成功) 回滚 + 自动重试
基础设施异常 网络超时、MQ 不可用、DB 主从切换 ✅ 可恢复(依赖外部恢复) 本地持久化 + 异步重试
服务不可用 下游服务宕机、 ✅ 可恢复(服务恢复后重试) 消息队列 + 死信机制
数据不一致 跨服务状态不同步(如订单已付但库存未扣) ⚠️ 部分可自动修复 对账 + 补偿

📌 企业原则

  • 业务异常 ≠ 系统异常:前者快速失败,后者必须重试
  • 绝不静默吞异常:所有异常必须记录 traceId 并分级告警

4.2 单体应用异常兜底方案

4.2.1 核心问题

  • 事务内异常导致回滚,但调用方不知情
  • 异步任务失败无追踪
  • 重试无上限导致雪崩

4.2.2 企业级解决方案

✅ 方案:事务边界清晰 + 异步任务可靠执行
java 复制代码
@Service
@RequiredArgsConstructor
public class OrderService {
    private final TaskReliableExecutor taskExecutor; // 可靠异步执行器

    @Transactional(rollbackFor = Exception.class)
    public Order createOrder(OrderRequest request) {
        // 1. 核心事务(快速提交)
        Order order = new Order(request);
        order.setStatus("CREATED");
        order = orderRepo.save();

        // 2. 提交后立即触发异步任务(不在事务内!)
        taskExecutor.submitReliableTask(
            "ORDER_PROCESS", 
            order.getId(), 
            () -> processOrderAsync(order.getId())
        );
        return order;
    }

    // 独立事务方法(由可靠执行器调用)
    @Transactional(rollbackFor = Exception.class)
    public void processOrderAsync(Long orderId) {
        try {
            inventoryService.reduceStock(orderId);
            paymentService.charge(orderId);
            orderRepo.updateStatus(orderId, "PAID");
        } catch (InsufficientStockException e) {
            // 业务异常:标记订单失败,不重试
            orderRepo.updateStatus(orderId, "FAILED", "库存不足");
            throw new BusinessException(e.getMessage());
        } catch (Exception e) {
            // 系统异常:抛出,由可靠执行器重试
            log.error("[orderId={}] 处理失败,将重试", orderId, e);
            throw e;
        }
    }
}
🔧 可靠异步执行器实现(带重试+持久化)
java 复制代码
@Component
public class TaskReliableExecutor {
    private final AsyncTaskRepository taskRepo;
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(4);

    public void submitReliableTask(String taskType, String businessKey, Runnable task) {
        // 1. 持久化任务到 DB(与主事务同库)
        AsyncTask asyncTask = new AsyncTask(taskType, businessKey, 0);
        taskRepo.save(asyncTask);

        // 2. 立即执行(或延迟执行)
        executeTask(asyncTask);
    }

    private void executeTask(AsyncTask task) {
        try {
            // 执行具体业务(通过反射或策略模式)
            taskStrategy.execute(task.getTaskType(), task.getBusinessKey());
            
            // 成功:删除任务
            taskRepo.deleteById(task.getId());
        } catch (BusinessException e) {
            // 业务异常:标记失败,不再重试
            taskRepo.markFailed(task.getId(), e.getMessage());
        } catch (Exception e) {
            // 系统异常:重试(最多5次,指数退避)
            int retryCount = task.getRetryCount() + 1;
            if (retryCount <= 5) {
                long delay = (long) Math.pow(2, retryCount) * 1000; // 2s, 4s, 8s...
                taskRepo.incrementRetry(task.getId());
                scheduler.schedule(() -> executeTask(task), delay, TimeUnit.MILLISECONDS);
            } else {
                // 超过重试次数:进入死信表,告警
                taskRepo.moveToDeadLetter(task.getId(), e.toString());
                alarmService.send("异步任务失败", task.toString());
            }
        }
    }
}

优势

  • 主流程无阻塞
  • 异常可追踪、可重试、可人工干预
  • 与主业务同库,避免分布式事务

4.3 分布式事务异常兜底方案

4.3.1 最终一致性(Outbox + MQ)兜底体系

四层防护机制:
防护层 组件 功能 企业级要求
第一层:发送可靠 Outbox 表 + 定时任务 确保消息不丢失 消息与业务同事务
第二层:消费幂等 Redis + DB 唯一索引 防重复消费 双保险去重
第三层:失败重试 MQ 死信队列(DLQ) 自动重试 + 隔离失败消息 重试策略可配置
第四层:人工兜底 补偿管理平台 查看/重试/跳过/修正 提供 Web UI
关键代码增强:死信队列处理
java 复制代码
// RabbitMQ 死信队列配置
@Bean
public Queue deadLetterQueue() {
    return QueueBuilder.durable("inventory.dlq").build();
}

@RabbitListener(queues = "inventory.dlq")
public void handleDeadLetter(Message message) {
    String payload = new String(message.getBody());
    String orderId = extractOrderId(payload);
    
    // 记录到补偿平台
    compensationService.recordFailure(
        "INVENTORY_REDUCE", 
        orderId, 
        new String(message.getBody()), 
        message.getMessageProperties().getRedelivered() ? "重试失败" : "首次失败"
    );
    
    // 发送企业微信/钉钉告警
    alarmService.sendCritical("库存扣减死信", "订单: " + orderId);
}

4.3.2 TCC 模式兜底体系

TCC 异常处理黄金法则:

"Try 可重试,Confirm/CANCEL 必须尽最大努力成功"

兜底措施:
  1. Cancel 失败告警

    java 复制代码
    @Override
    public boolean cancel(BusinessActionContext ctx) {
        try {
            inventoryRepo.releaseFrozen(ctx.getActionContext("orderId"));
            return true;
        } catch (Exception e) {
            // 立即触发 P0 级告警
            alarmService.sendP0("TCC Cancel 失败", ctx.getXid(), e);
            // 尝试备用方案(如调用 Admin API 手动释放)
            adminApi.releaseFrozenInventory(ctx.getActionContext("orderId"));
            return false; // Seata 会记录日志
        }
    }
  2. Confirm 失败人工介入

    • Seata 控制台提供 "悬挂事务" 列表
    • 运维可手动 Commit / Rollback
  3. 全局事务日志归档

    • undo_log 表每日归档至冷存储
    • 保留 180 天用于审计

4.4 企业级容灾四件套

4.4.1 幂等性(所有入口统一治理)

java 复制代码
// 通用幂等注解(支持 SpEL)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Idempotent {
    String key() default "#requestId"; // 默认取 requestId
    long expireSeconds() default 3600;
}

// AOP 实现(Redis + 本地缓存二级)
@Aspect
public class IdempotentAspect {
    @Around("@annotation(idempotent)")
    public Object handle(ProceedingJoinPoint jp, Idempotent idempotent) {
        String key = parseSpel(idempotent.key(), jp.getArgs());
        String redisKey = "IDEMPOTENT:" + key;
        
        // 1. 本地缓存快速判断(Caffeine)
        if (localCache.getIfPresent(redisKey) != null) {
            throw new DuplicateRequestException();
        }
        
        // 2. Redis 分布式锁(SET NX EX)
        Boolean acquired = redis.setIfAbsent(redisKey, "1", Duration.ofSeconds(idempotent.expireSeconds()));
        if (Boolean.FALSE.equals(acquired)) {
            throw new DuplicateRequestException();
        }
        
        try {
            Object result = jp.proceed();
            localCache.put(redisKey, result); // 缓存结果(可选)
            return result;
        } finally {
            // 不主动删除,靠 TTL 自动过期(防重试期间误删)
        }
    }
}

4.4.2 补偿管理平台(人工兜底)

  • 功能清单

    • 查看失败事件列表(按服务/时间/类型过滤)
    • 一键重试 / 批量重试
    • 跳过(标记为成功)
    • 数据修正(直接调用 Admin API)
    • 导出 CSV 用于对账
  • 技术实现

    sql 复制代码
    CREATE TABLE compensation_task (
        id BIGINT PRIMARY KEY,
        service_name VARCHAR(100),
        event_type VARCHAR(100),
        business_key VARCHAR(100),
        payload JSON,
        status ENUM('FAILED', 'RETRIED', 'SKIPPED'),
        error_message TEXT,
        created_at DATETIME,
        updated_at DATETIME
    );

4.4.3 对账系统(数据一致性最后防线)

  • 对账类型

    对账类型 频率 说明
    实时对账 事件驱动 关键操作后立即核对(如支付成功后查库存)
    准实时对账 5分钟一次 扫描最近变更数据
    离线对账 每日凌晨 全量比对(T+1)
  • 对签示例(离线)

    java 复制代码
    @Scheduled(cron = "0 0 2 * * ?")
    public void dailyReconciliation() {
        List<ReconcileItem> mismatches = reconciliationService.findMismatches(
            LocalDate.now().minusDays(1)
        );
        
        for (ReconcileItem item : mismatches) {
            if (item.canAutoFix()) {
                autoFixService.fix(item);
            } else {
                // 生成工单,通知运营
                ticketService.create("数据不一致", item.toString());
                alarmService.send("对账失败", item.getBusinessKey());
            }
        }
    }

4.4.4 可观测性(三位一体)

维度 工具 关键指标
Trace SkyWalking / Zipkin 事务链路耗时、异常节点
Metrics Prometheus + Grafana Outbox 积压数、MQ 消费延迟、TCC 异常率
Log ELK / Loki 按 traceId 聚合日志,标记 [TXN]

Grafana 告警规则示例

  • outbox_pending_count > 100 → P2 告警
  • tcc_cancel_failure_rate > 0 → P0 告警

4.5 企业级上线 Checklist(异常兜底专项)

检查项 验证方式 负责人
所有对外 API 支持 X-Request-ID Postman 测试 开发
MQ 消费者实现幂等 模拟重复消息 开发
Outbox 定时任务覆盖所有事件类型 代码审查 架构师
补偿平台可查看最近 7 天失败事件 UI 验收 测试
对账任务每日运行且有报告 检查日志 SRE
TCC 的 Cancel 方法有 P0 告警 Chaos 演练 SRE
所有异常包含 traceId 日志采样检查 SRE

本章核心思想
"没有完美的事务,只有完备的兜底"

企业级系统不追求 100% 不出错,而是确保 "错可发现、错可恢复、错可追溯"


五、企业级 Checklist

类别 检查项 是否完成
事务设计 所有 @Transactional 明确 rollbackFor
避免 this 调用、非 public 方法
幂等性 API 层:X-Request-ID 去重
MQ 消费:Redis + DB 双幂等
异常处理 不吞异常,系统异常可重试
业务异常快速失败,不重试
可观测性 全链路 TraceID 透传
关键指标告警(积压 > 100)
容灾 对账任务每日运行
补偿平台支持人工干预
压测 模拟 2 倍峰值流量
混沌演练(网络分区、DB 故障)

六、总结:企业级事务架构建议

场景 推荐方案 关键保障
单体高并发 乐观锁 + 异步解耦 细粒度事务、分段锁
普通微服务 Outbox + MQ 幂等消费、补偿平台、对账
金融强一致 Seata TCC Cancel 幂等、人工兜底
超长流程 Saga 编排 补偿可重试、状态机持久化

终极原则

  • 简单优于复杂:能用最终一致就不用 TCC
  • 可观测性 > 事务本身:没有监控的事务等于没有事务
  • 对账是最后一道防线:再完美的事务也需要对账兜底
相关推荐
Prince-Peng3 小时前
技术架构系列 - 详解Redis
数据结构·数据库·redis·分布式·缓存·中间件·架构
你才是臭弟弟3 小时前
SpringBoot 集成MinIo(根据上传文件.后缀自动归类)
java·spring boot·后端
what丶k4 小时前
SpringBoot3 配置文件使用全解析:从基础到实战,解锁灵活配置新姿势
java·数据库·spring boot·spring·spring cloud
RwTo4 小时前
【源码】- SpringBoot启动
java·spring boot·spring
Elieal4 小时前
JWT 登录校验机制:5 大核心类打造 Spring Boot 接口安全屏障
spring boot·后端·安全
czlczl200209254 小时前
Spring Boot Filter :doFilter 与 doFilterInternal 的差异
java·spring boot·后端
码界奇点4 小时前
基于Spring Boot和Activiti6的工作流OA系统设计与实现
java·spring boot·后端·车载系统·毕业设计·源代码管理
yangminlei4 小时前
Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实战指南
java·spring boot·后端
曹天骄5 小时前
基于 Cloudflare Worker + KV 构建高性能分布式测速调度系统(工程实战)
分布式
czlczl200209255 小时前
Spring Boot :彻底解决 HttpServletRequest 输入流只能读取一次的问题
java·spring boot·后端