Quarkus中@Transactional标注的定时方法偶发无事务错误是什么原因?
问题根因
从报错堆栈可以直接定位到三个核心触发点:
- 拦截器执行顺序异常:你类上标注的
@Traced对应的OpenTracing拦截器优先级默认高于事务拦截器,从调用栈可以看到事务拦截器的执行被包裹在链路追踪拦截器内部,偶发情况下链路拦截器执行时会污染事务上下文,导致事务拦截器误判当前存在已激活事务,尝试加入后实际事务已失效。 - 调度任务并发冲突:你配置的cron任务执行间隔为1分钟,Quarkus的
@Scheduled默认允许同身份任务并发执行,若某次任务执行耗时超过1分钟,就会出现多个任务并行执行的情况,前一个任务的事务上下文未完全清理,就会导致新任务拿到失效的事务上下文,抛出no transaction is in progress异常。 - 版本已知问题:Quarkus 2.5.1版本存在调度场景下事务拦截器偶发未正确创建新事务的BUG,该问题在2.6及后续稳定版已修复。
修复方案
按优先级顺序处理即可:
- 首先禁止同身份任务并发执行,给
@Scheduled添加并发控制参数:
@Scheduled(cron = "0 * * ? * *", identity = "boss-job", concurrentExecution = Scheduled.ConcurrentExecution.SKIP)
ConcurrentExecution.SKIP表示如果上一次任务还未执行完成,直接跳过本次触发,避免事务上下文串扰。
- 显式指定事务传播级别为
REQUIRES_NEW,强制每次执行都创建独立新事务,避免复用失效上下文:
@Transactional(Transactional.TxType.REQUIRES_NEW)
- 若上述修改后仍偶发异常,可以在
application.properties中调整拦截器优先级,确保事务拦截器先执行:
# 优先级数字越小,执行顺序越靠前 quarkus.transaction.interceptor.priority=0 quarkus.opentracing.interceptor.priority=100
- 有升级条件的话,可以将Quarkus版本升级到2.6+的稳定版,修复底层已知问题。
内容的提问来源于stack exchange,提问作者Benjamin Gamard
相关产品推荐
相关产品推荐

