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
相关产品推荐
相关产品推荐

