You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring MVC容器管理事务下DAO/流程层异常处理及返回Response Code1问询

Hey there, let's walk through how to set up the exception handling exactly for your Spring MVC stack, matching your layer structure and requirement to return Response Code 1 on technical failures. Let's break this down step by step:

1. First, Define a Custom Technical Exception

We need a clear way to mark technical failures (like DB connection issues, JPA persistence errors, IO glitches) separate from business exceptions. Create a TechnicalException that extends RuntimeException—this plays nice with Spring's container-managed transactions, since they auto-rollback on runtime exceptions by default:

public class TechnicalException extends RuntimeException {
    public TechnicalException(String message) {
        super(message);
    }

    public TechnicalException(String message, Throwable cause) {
        super(message, cause);
    }
}
2. DAO Layer Exception Handling

Since you're using JPA, Spring automatically converts JPA's PersistenceException into subclasses of DataAccessException (think JpaSystemException or DataIntegrityViolationException). Instead of catching exceptions directly in the DAO layer (which could break transaction rollbacks), let them bubble up to the Service layer, where we'll wrap them into our custom TechnicalException:

@Service
public class YourBusinessService {
    private final YourDAO yourDAO;
    private final Logger log = LoggerFactory.getLogger(YourBusinessService.class);

    // Constructor injection (preferred over @Autowired)
    public YourBusinessService(YourDAO yourDAO) {
        this.yourDAO = yourDAO;
    }

    public void executeDBOperation() {
        try {
            yourDAO.performPersistOrFetch();
        } catch (DataAccessException e) {
            log.error("Failed to execute database operation", e);
            throw new TechnicalException("Database operation failed", e);
        }
    }
}

If your DAO has custom technical issues (like a custom data source error), you can directly throw TechnicalException from the DAO itself.

3. Process Layer Exception Handling

The Process layer is your workflow orchestration hub—here you'll catch technical exceptions from the Service layer, handle any layer-specific technical issues (like external service timeouts, IO errors), and ensure all technical failures get wrapped into TechnicalException before bubbling up:

@Component
public class YourProcessHandler {
    private final YourBusinessService businessService;
    private final Logger log = LoggerFactory.getLogger(YourProcessHandler.class);

    public YourProcessHandler(YourBusinessService businessService) {
        this.businessService = businessService;
    }

    public void runWorkflow() {
        try {
            businessService.executeDBOperation();
            // Run your process-specific logic here
            performProcessSteps();
        } catch (TechnicalException e) {
            log.error("Workflow hit a technical failure", e);
            throw e; // Pass up to Delegate/Controller for global handling
        } catch (IOException e) {
            log.error("IO error during workflow execution", e);
            throw new TechnicalException("Workflow IO operation failed", e);
        }
    }

    private void performProcessSteps() throws IOException {
        // Your process logic that might throw IO or other technical errors
    }
}

Don't swallow exceptions here—pass them up so the global handler can format the correct response for the UI.

4. Global Exception Handler to Return Response Code 1

Use Spring's @RestControllerAdvice to create a global exception handler that catches TechnicalException and returns the required Response Code 1 in the JSON response. This keeps your controllers clean and ensures consistent error formatting:

@RestControllerAdvice
public class GlobalExceptionHandler {
    private final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(TechnicalException.class)
    public ResponseEntity<Map<String, Object>> handleTechnicalFailure(TechnicalException e) {
        log.error("Handling technical failure for UI response", e);
        
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("responseCode", 1);
        errorResponse.put("message", "Technical failure occurred, please try again later");
        
        // If you need to return a 200 HTTP status (instead of 500) for UI compatibility, swap to HttpStatus.OK
        return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

Adjust the HTTP status code based on your UI's requirements—some teams prefer returning 200 with a response code in the body, others use 500 for server errors.

5. Container-Managed Transaction Tips

Since you're using container-managed transactions (via @Transactional), remember:

  • Our TechnicalException is a runtime exception, so Spring will auto-rollback transactions when it's thrown—perfect for data consistency.
  • If you ever use checked exceptions, you'll need to add rollbackFor = YourCheckedException.class to the @Transactional annotation to trigger rollbacks.
Quick Best Practices
  • Log Everything: Always log full exception stacks in the layers where you catch exceptions—this is critical for debugging production issues.
  • Separate Business vs Technical Exceptions: If you have business-specific errors (like "user not found"), create a separate BusinessException so you can handle those differently (return a different response code, for example).
  • Keep Controllers Lean: Don't handle exceptions in controllers—let the global advice take care of it, so controllers focus on request/response mapping.

内容的提问来源于stack exchange,提问作者Gunjan Shah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:21:37