0

我正在寻找一个干净的解决方案来让事务启动的监听器。这意味着我希望侦听器在Spring上下文中成为一个bean(组件),在开始新事务的时候,事务将从TransactionPlatformManager或Hibernate Session或类似的事件接收事务。事务开始时的监听器

东西一起:

@Component 
class TransactionListener implements ?? { 

    @Autowired 
    private Something x; 

    public void onTransactionBegin(...) { 
     x.doSomething() 
    } 

} 

要具体,我减轻系统范围的问题,我需要设置一个线程本地事务开始时,这样我就可以当地的继续访问该线程处于休眠的处理实体来检索信息。

我调查了消息来源,发现这样的听众无法实现。我发现的唯一解决方案是继承HibernateTransactionManager和它的doBegin()方法,我不觉得特别好。

+0

最简单的可能是为“PlatformTransactionManager”创建一个包装,并在3个方法调用上触发这些事件。但为什么你需要注册?你在做什么?你提到解决问题,但这似乎有点奇怪。 –

+0

我面临的问题是无关紧要的,它是由我们的大型多模块架构引起的。如果我有选择作出有关架构的决定,我会以不同的方式做。但这在传统架构中是不可能的,没有沉浸式重写,这就是为什么我需要这个。 – redhead

回答

1

Spring在其TransactionSynchronization中有一些事务回调,但正如您已经注意到的那样,没有回调事务开始,我的错误。

据我所知,Spring不会让你知道事务何时开始,尽管这可能会因实现PlatformTransactionManager而有所不同。如果你想挂接到Spring的事务,我相信你会留下

  1. 子类的事务管理器和调用一些回调
  2. @Transactional带弹簧的AOP创建一个建议(这一点,如果你使用注解只会工作,很明显)

如果您在使用Hibernate,你可能有一些运气afterTransactionBeginhttps://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/Interceptor.html#afterTransactionBegin(org.hibernate.Transaction)

+0

这将通知所有的事件,*除了交易开始。 – Andreas

+0

对不起,在手机上,更新了答案 – gogstad

0

这为我工作至今。

@Aspect 
@Component 
public class StartTransactionInterceptor { 

    @Pointcut("target(org.springframework.transaction.PlatformTransactionManager)") 
    public void isPlatformTransactionManager() { 
    } 

    @Pointcut("execution(org.springframework.transaction.TransactionStatus getTransaction(" 
      + "org.springframework.transaction.TransactionDefinition)))") 
    public void getsTransaction() { 
    } 

    @Around("isPlatformTransactionManager() && getsTransaction()") 
    public Object registerSynchronization(ProceedingJoinPoint joinPoint) throws Throwable { 
     TransactionStatus value = (TransactionStatus)joinPoint.proceed(); 
     if (value.isNewTransaction()) { 
      // send some application event to others who are interested 
     } 
     return value; 
    } 
} 

或者,您可以使用Spring的SimpleTransactionScope并为事务处理作用域的作用域。当其他人在事务中调用下面的DealWithStuffPerTx.addMoreStuff(Object)时,该bean将被懒惰地实例化。

@Configuration 
public class TransactionScopeConfig implements BeanFactoryPostProcessor { 

    public static final String NAME = "tx"; 
    @Override 
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 
     beanFactory.registerScope(NAME, new SimpleTransactionScope()); 
    } 
} 

@Component 
@Scope(value = TransactionScopeConfig.NAME, proxyMode = ScopedProxyMode.TARGET_CLASS) 
public class DealWithStuffPerTx extends TransactionSynchronizationAdapter { 

    public void addMoreStuff(Object stuff) { 
    } 

    @Override 
    public void afterCommit() { 
     // deal with stuff 
    } 

    @PostConstruct 
    public void init() { 
     TransactionSynchronizationManager.registerSynchronization(this); 
    } 
}