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

Quarkus整合Kafka与Hibernate时事务获取失败问题

解决方案

问题根源在于你手动实例化了AlertService,导致它并非CDI托管Bean,@Transactional注解无法通过CDI代理生效,同时EntityManager也没有活跃的上下文可用。以下是具体修正步骤:

1. 修正AlertService的CDI托管与事务配置

将事务方法改为public(CDI代理仅能拦截public方法以生效事务),同时在process方法上直接添加事务注解,确保执行时激活事务上下文:

@ApplicationScoped
public class AlertService implements Processor<String, QuineOutput, Object, Object> {
    private final EntityManager em;

    // 由CDI注入EntityManager,禁止手动传参
    @Inject
    public AlertService(EntityManager em) {
        this.em = em;
    }

    @Transactional
    public void persistAlert(Alert alert) {
        em.persist(alert);
    }

    @Override
    @Transactional // 触发事务上下文激活
    public void process(Record<String, QuineOutput> record) {
        Log.warn("here for persist");
        persistAlert(record.value().getData().getAlertNode());
    }

    // 必须实现Processor接口的其他生命周期方法
    @Override
    public void init(ProcessorContext context) {
        // 初始化逻辑(如保存上下文)
    }

    @Override
    public void close() {
        // 资源清理逻辑
    }
}

2. 修正拓扑构建代码,使用CDI托管实例

不要手动new AlertService(em),改为通过CDI注入实例后传递给process方法:

@Inject
EntityManager em;

@Inject
AlertService alertService; // 注入CDI托管的AlertService实例

...

StreamsBuilder streamsBuilder = new StreamsBuilder();

...

// 传入CDI托管的实例,而非手动创建
streamsBuilder.stream(rdbmsTopic, Consumed.with(Serdes.String(), QUINE_ALERT_SERDES))
              .process(() -> alertService);

3. 额外注意事项

  • 确保项目已添加必要Quarkus扩展:quarkus-hibernate-orm、quarkus-jdbc-postgresql、quarkus-kafka-streams、quarkus-narayana-jta(事务扩展默认已包含);
  • Kafka Streams线程独立于Quarkus请求线程,必须通过@Transactional自动激活事务上下文,不可依赖请求上下文;
  • 确认Alert实体类正确标注@Entity,且数据源配置无误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:42:34