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

