Java业务状态冲突处理的核心是前置校验与自定义异常拦截:通过状态图白名单校验、Service层抛出带领域语义的RuntimeException(如OrderStatusConflictException),并在@ControllerAdvice中统一返回400响应及结构化日志。

Java 中处理业务状态冲突,核心是用自定义异常把“不该发生的跳转”显式拦截下来,而不是等数据库报错或逻辑出乱后再兜底。它不是补救手段,而是前置守门员。
明确状态冲突的边界
状态冲突指业务规则禁止的状态流转,比如订单从「已发货」回退到「待支付」,或用户从「禁用」直接切到「超级管理员」。这类问题不能靠 try-catch 捕获 SQL 异常来解决,必须在 service 层校验时就识别并拒绝。
- 先画出合法状态图(可用枚举 + Map<String, Set<String>> 表示每个状态允许跳转到哪些目标状态)
- 校验逻辑放在真正更新数据库之前,不满足即抛异常,不执行后续操作
- 避免把状态校验和数据持久化混在同一方法里,职责要分离
设计专用异常类
推荐命名为 OrderStatusConflictException、UserRoleTransitionException 这类带领域语义的名字,继承 RuntimeException,不强制上层捕获,但便于全局统一处理。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 构造函数至少包含:订单 ID(或用户 ID)、当前状态、目标状态、可选错误码
- 重写 toString() 或提供 getter 方法,方便日志提取关键字段
- 不需覆盖 printStackTrace(),默认行为已足够清晰
在 Service 层主动抛出
不要等 DAO 层返回 null 或更新行数为 0 才反应。要在调用 update 方法前完成判断:
立即学习“Java免费学习笔记(深入)”;
- 查出当前实体,拿到它的 status 字段
- 调用 isValidTransition(current, target) 方法做白名单校验
- 校验失败立即 throw 新建的异常实例,消息中带上 orderId 和两个状态值
- 确保事务注解 @Transactional 不会因异常未被捕获而意外回滚非业务性操作(如状态冲突本就不该改库)
配合全局异常处理器输出结构化响应
Spring 项目中用 @ControllerAdvice 拦截该异常,返回标准 JSON:
- HTTP 状态码建议用 400(Bad Request),不是服务端错误
- 响应体含 error_code(如 ORDER_STATUS_ILLEGAL)、message、timestamp、以及 orderId 等上下文字段
- 同时记录结构化日志,例如用 MDC 放入 orderId,方便链路追踪

















