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); 
    } 
}