Spring @Retryable注解测试失败,重试不生效问题排查求助
可能的问题及排查步骤
1. 确认Accessor类是Spring管理的Bean
Spring Retry依赖AOP代理,只有被Spring容器管理的Bean才能触发@Retryable逻辑。检查你的test-config.xml是否通过<context:component-scan>扫描到了Accessor所在的包,或者是否显式将Accessor定义为<bean>。如果Accessor不是Spring Bean,重试逻辑完全不会生效。
2. 检查maxAttemptsExpression的配置值
你用了${retry.maxAttempts}指定重试次数,需要确认:
- 测试环境的配置文件(比如
application-test.properties或test-config.xml内的配置)是否存在该属性,且值大于1(例如retry.maxAttempts=3)。 - 如果配置未正确加载,
maxAttempts会默认设为1,自然不会触发重试。可以临时将maxAttemptsExpression替换为固定值maxAttempts=3测试,排除配置加载问题。
3. 验证异常类型是否完全匹配
虽然代码捕获并抛出了UncategorizedSQLException,但要确认:
- 抛出的异常是否是直接的
UncategorizedSQLException,有没有被上层代码包装成RuntimeException或其他类型?可以在测试中打印异常的完整栈轨迹,确认实际抛出的异常类型。 - 检查
@Retryable的include属性是否覆盖了实际抛出的异常,比如如果是SQLException的子类,是否被正确包含。
4. 排查自定义重试监听器的影响
你的@Retryable指定了listeners={"customRetryListener"},可以先去掉这个配置,测试重试是否生效。如果去掉后重试正常,说明自定义监听器的逻辑存在问题(比如监听器抛出异常中断了重试流程)。
5. 确认@EnableRetry的生效范围
你在测试类上加了@EnableRetry,但要确认:
- 该注解是否被Spring正确识别,或者是否应该加在配置类上(比如test-config.xml对应的配置类)。如果test-config.xml里已经配置了
<retry:annotation-driven/>,则无需重复添加@EnableRetry,避免冲突。
测试验证小技巧
可以在accessorMethod中添加日志打印,每次调用时输出当前时间或调用次数,直观判断是否触发重试:
@Retryable(...) public String accessorMethod(final String parameter) { log.info("accessorMethod 第{}次调用,参数:{}", Instant.now(), parameter); try { ... } catch (UncategorizedSQLException exception) { log.error("抛出UncategorizedSQLException", exception); throw exception; } catch (final Exception exception) { return null; } }
执行测试后查看日志,若只打印一次,说明重试未触发;若打印多次,则重试逻辑生效。
内容的提问来源于stack exchange,提问作者MinionAttack
相关产品推荐
相关产品推荐

