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

