2014-09-08 11 views
11

Muszę publikować zdarzenia powiadomień do systemów zewnętrznych przez JMS, gdy dane są aktualizowane. Należy to zrobić w ramach tej samej transakcji, ponieważ obiekty są zatwierdzone do bazy danych w celu zapewnienia integralności.Obsługa zdarzeń aplikacji związanych ze sprężyną i danymi w ramach transakcji

Zdarzenia ApplicationLifecycle, które emitują dane z wiosny, wydają się logicznym miejscem do wdrożenia tej logiki.

@org.springframework.transaction.annotation.Transactional 
public class TestEventListener extends AbstractRepositoryEventListener<Object> { 

    private static final Logger LOG = LoggerFactory.getLogger(TestEventListener.class); 

    @Override 
    protected void onBeforeCreate(Object entity) { 
     LOG.info("XXX before create"); 
    } 

    @Override 
    protected void onBeforeSave(Object entity) { 
     LOG.info("XXX before save"); 
    } 

    @Override 
    protected void onAfterCreate(Object entity) { 
     LOG.info("XXX after create"); 
    } 

    @Override 
    protected void onAfterSave(Object entity) { 
     LOG.info("XXX after save"); 
    } 

} 

Jednak te zdarzenia mają miejsce przed i po uruchomieniu tx i zatwierdzeniu.

08 15:32:37.119 [http-nio-9000-exec-1] INFO n.c.v.vcidb.TestEventListener - XXX before create 
08 15:32:37.135 [http-nio-9000-exec-1] TRACE o.s.t.i.TransactionInterceptor - Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save] 



08 15:32:37.432 [http-nio-9000-exec-1] TRACE o.s.t.i.TransactionInterceptor - Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save] 
08 15:32:37.479 [http-nio-9000-exec-1] INFO n.c.v.vcidb.TestEventListener - XXX after create 

Jaki punkt rozszerzenia ma spring-data-rest dla dodania zachowania, które zostanie wykonane w ramach wiosennej transakcji zarządzanej?

+0

Czy to zorientowali się? Stając wobec tego samego problemu w tej chwili. – Daniel

+0

Brak rozwiązania, jak się obawiam. –

Odpowiedz

7

użyć AOP (punkt przekroju tx i inne), aby rozwiązać ten problem:

@Configuration 
@ImportResource("classpath:/aop-config.xml") 
public class AopConfig { ... 

i AOP-config.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
         http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop.xsd 
         http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx.xsd" 
    default-autowire="byName"> 

    <aop:config> 
     <aop:pointcut id="restRepositoryTx" 
      expression="execution(* org.springframework.data.rest.webmvc.RepositoryEntityController.*(..))" /> 
     <aop:advisor id="managerTx" advice-ref="txAdvice" pointcut-ref="restRepositoryTx" order="20" /> 
    </aop:config> 

    <tx:advice id="txAdvice" transaction-manager="transactionManager"> 
     <tx:attributes> 
      <tx:method name="postCollectionResource*" propagation="REQUIRES_NEW" rollback-for="Exception" /> 
      <tx:method name="putItemResource*" propagation="REQUIRES_NEW" rollback-for="Exception" /> 
      <tx:method name="patchItemResource*" propagation="REQUIRES_NEW" rollback-for="Exception" /> 
      <tx:method name="deleteItemResource*" propagation="REQUIRES_NEW" rollback-for="Exception" /> 
      <!-- <tx:method name="*" rollback-for="Exception" /> --> 
     </tx:attributes> 
    </tx:advice> 

</beans> 

ten jest taki sam jak po metody opisywane kontroler z @Transactional.

+0

podczas wypisywania tekstu/listy uri w celu aktualizacji właściwości osadzonej należy również włączyć org.springframework.data.rest.webmvc.RepositoryPropertyReferenceController.createPropertyReference w konfiguracji AOP – Korgen

0

Nie pracowałem przy wiosennych danych, ale wiosną można to zrobić w następujący sposób.

1) Zdefiniuj niestandardowy adapter TransactionSynchronization i zarejestruj komponent bean w menedżerze transakcji TransactionSynchronizationManager.

Zwykle mam metodę registerSynchronizaiton z @ pointefad do tego celu.

@SuppressWarnings("rawtypes") @Before("@annotation(org.springframework.transaction.annotation.Transactional)") 
    public void registerSynchronization() { 
     // TransactionStatus transStatus = TransactionAspectSupport.currentTransactionStatus(); 
     TransactionSynchronizationManager.registerSynchronization(this); 
     final String transId = UUID.randomUUID().toString(); 
     TransactionSynchronizationManager.setCurrentTransactionName(transId); 
     transactionIds.get().push(transId); 
     if (TransactionSynchronizationManager.isActualTransactionActive() && TransactionSynchronizationManager 
      .isSynchronizationActive() && !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { 
      if (!TransactionSynchronizationManager.hasResource(KEY)) { 
       final List<NotificationPayload> notifications = new ArrayList<NotificationPayload>(); 
       TransactionSynchronizationManager.bindResource(KEY, notifications); 
      } 
     } 
    } 

2) I zaimplementować metodę Zastąp następująco

@Override public void afterCompletion(final int status) { 
    CurrentContext context = null; 
    try { 
     context = ExecutionContext.get().getContext(); 
    } catch (final ContextNotFoundException ex) { 
     logger.debug("Current Context is not available"); 
     return; 
    } 
    if (status == STATUS_COMMITTED) { 
     transactionIds.get().removeAllElements(); 
     publishedEventStorage.sendAllStoredNotifications(); 
     // customize here for commit actions 
    } else if ((status == STATUS_ROLLED_BACK) || (status == STATUS_UNKNOWN)) { 
     // you can write your code for rollback actions 
    } 
} 
+0

W tej metodzie, gdzie definiujemy metody chcesz zawinąć w transakcję? –

+0

Przepraszamy za bardzo późną odpowiedź, użyj AOP dla metod, które wymagają synchronizacji transakcyjnej –

Powiązane problemy