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

如何在Quarkus中获取当前事务的TxType属性值?

获取Quarkus事务中@Transactional注解的属性值

在Quarkus中,你可以通过以下两种方式获取当前事务对应的@Transactional注解属性(比如TxType):

1. 在CDI拦截器中直接获取注解

如果你的扩展是基于CDI拦截器实现(与事务拦截器协同工作),可以通过InvocationContext直接获取方法或类上的@Transactional注解:

import jakarta.interceptor.AroundInvoke;
import jakarta.interceptor.Interceptor;
import jakarta.interceptor.InvocationContext;
import jakarta.transaction.Transactional;

@Interceptor
// 可自定义绑定注解或调整优先级,确保拦截时机符合需求
public class TxAttributeInterceptor {

    @AroundInvoke
    public Object intercept(InvocationContext ctx) throws Exception {
        // 优先获取方法上的注解,无则获取类上的
        Transactional txAnnotation = ctx.getMethod().getAnnotation(Transactional.class);
        if (txAnnotation == null) {
            txAnnotation = ctx.getTarget().getClass().getAnnotation(Transactional.class);
        }

        if (txAnnotation != null) {
            Transactional.TxType txType = txAnnotation.value();
            String rollbackOnClassName = txAnnotation.rollbackOn()[0].getName();
            // 处理获取到的属性值
        }

        return ctx.proceed();
    }
}

2. 在事务执行过程中通过事务同步注册表传递属性

如果需要在业务方法内部或任意事务上下文位置获取注解属性,可以在事务启动时将注解属性存入TransactionSynchronizationRegistry,后续随时取出使用:

步骤1:编写拦截器捕获并存储注解属性

import jakarta.inject.Inject;
import jakarta.interceptor.AroundInvoke;
import jakarta.interceptor.Interceptor;
import jakarta.interceptor.InvocationContext;
import jakarta.transaction.Transactional;
import jakarta.transaction.TransactionSynchronizationRegistry;

@Interceptor
@Transactional // 可通过@Priority调整拦截顺序,确保在事务拦截器前后执行
public class TxAttributeCaptureInterceptor {

    @Inject
    TransactionSynchronizationRegistry tsr;

    @AroundInvoke
    public Object captureTxAttrs(InvocationContext ctx) throws Exception {
        Transactional txAnnotation = ctx.getMethod().getAnnotation(Transactional.class);
        if (txAnnotation == null) {
            txAnnotation = ctx.getTarget().getClass().getAnnotation(Transactional.class);
        }

        if (txAnnotation != null) {
            tsr.putResource("tx-type", txAnnotation.value());
            tsr.putResource("tx-rollbackOn", txAnnotation.rollbackOn());
        }

        try {
            return ctx.proceed();
        } finally {
            // 事务结束后清理资源,避免污染后续事务
            if (txAnnotation != null) {
                tsr.removeResource("tx-type");
                tsr.removeResource("tx-rollbackOn");
            }
        }
    }
}

步骤2:在需要的位置获取属性

import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.transaction.TransactionSynchronizationRegistry;

public class SomeTransactionalService {

    @Inject
    TransactionSynchronizationRegistry tsr;

    @Transactional(value = Transactional.TxType.REQUIRED, rollbackOn = Exception.class)
    public void doBusiness() {
        Transactional.TxType currentTxType = (Transactional.TxType) tsr.getResource("tx-type");
        Class<?>[] rollbackOnTypes = (Class<?>[]) tsr.getResource("tx-rollbackOn");
        
        // 使用获取到的属性做逻辑处理
        if (currentTxType == Transactional.TxType.REQUIRED) {
            // 执行对应逻辑
        }
    }
}

注意事项

  • 方法级别的@Transactional注解会覆盖类级别的,所以需要优先检查方法上的注解。
  • 可通过@Priority注解调整拦截器执行顺序,确保你的拦截器在Quarkus默认事务拦截器的合适时机运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 21:32:47