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

Quarkus中@Transactional注解报错:事务未激活问题求助

解决Quarkus @Transactional方法执行超时引发的ARJUNA016102 RollbackException

这个错误的核心原因是事务超时被自动终止了。Quarkus默认的事务超时时间通常为60秒,而你的方法总执行时长达到了110秒(10秒初始sleep + 10次10秒sleep),远超默认阈值。Arjuna事务管理器会主动终止超时的事务,后续执行persist操作时,就会提示事务已不活跃。

以下是几种可行的解决方式:

1. 单独设置当前方法的事务超时

直接在@Transactional注解中指定超时时间(单位:秒),覆盖默认值,确保时长足够覆盖业务执行:

@GET
@Path("/test")
@Produces(MediaType.TEXT_PLAIN)
@Transactional(timeout = 120) // 设置事务超时为120秒
public String test() throws Exception {

    Thread.sleep(10000);
    Test test = new Test();
    test.name = "xxx";
    test.persist();
    
    for (int i = 0; i < 10; i++) {
        Thread.sleep(10000);
        test = new Test();
        test.name = "xxx";
        test.persist();
    }

    return "ok";
}

2. 全局配置事务超时时间

如果多个业务方法都需要长事务,可以在application.properties中配置全局默认超时:

quarkus.transaction-manager.default-timeout=120

同样以秒为单位,根据实际业务需求调整数值。

3. 拆分长事务为多个短事务(推荐)

长时间持有一个事务会占用数据库连接、事务资源,还容易引发锁竞争问题。更合理的做法是把业务拆分成多个独立的短事务:

@GET
@Path("/test")
@Produces(MediaType.TEXT_PLAIN)
public String test() throws Exception {
    Thread.sleep(10000);
    saveTestRecord();
    
    for (int i = 0; i < 10; i++) {
        Thread.sleep(10000);
        saveTestRecord();
    }

    return "ok";
}

// 每个数据持久化操作单独开启事务
@Transactional
void saveTestRecord() {
    Test test = new Test();
    test.name = "xxx";
    test.persist();
}

这样每个saveTestRecord方法的事务独立执行,即使某个步骤耗时较长,也不会影响其他操作,同时避免了长时间占用同一事务资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:46:15