2014-09-08 13 views
11

Tôi cần xuất bản các sự kiện thông báo cho các hệ thống bên ngoài qua JMS, khi dữ liệu được cập nhật. Id như thế này được thực hiện trong cùng một giao dịch khi các đối tượng được cam kết với cơ sở dữ liệu để đảm bảo tính toàn vẹn.Xử lý các sự kiện ứng dụng phần còn lại dữ liệu trong giao dịch

Các sự kiện ApplicationLifecycle phát hiện phần còn lại dữ liệu vào mùa xuân có vẻ như là nơi hợp lý để triển khai logic này.

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

} 

Tuy nhiên, những sự kiện này xảy ra trước và sau khi bắt đầu và cam kết.

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 

Điểm mở rộng dữ liệu của mùa xuân có thêm hành vi sẽ thực hiện trong giao dịch mùa xuân được quản lý không?

+0

Bạn đã figured này ra? Đối mặt với cùng một vấn đề ngay bây giờ. – Daniel

+0

Không có giải pháp nào nhưng tôi sợ. –

Trả lời

7

tôi sử dụng AOP (pointcut và tư vấn tx) để giải quyết vấn đề này:

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

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> 

này cũng giống như khi các phương pháp điều khiển chú thích với @Transactional.

+0

khi bạn PUTing văn bản/danh sách uri để cập nhật thuộc tính nhúng, bạn cũng cần phải bao gồm org.springframework.data.rest.webmvc.RepositoryPropertyReferenceController.createPropertyReference trong cấu hình AOP của bạn – Korgen

0

Tôi chưa làm việc trên phần còn lại của dữ liệu vào mùa xuân, nhưng với mùa xuân, điều này có thể được xử lý theo cách sau.

1) Xác định TransactionSynchronizationAdapter tùy chỉnh và đăng ký bean trong TransactionSynchronizationManager.

Thông thường, tôi có phương thức registerSynchronizaiton với dấu @Before cho điều này.

@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) Và, thực hiện phương pháp ghi đè như sau

@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

Với phương pháp này, chúng ta định nghĩa phương thức chúng ta làm ở đâu muốn gói trong giao dịch? –

+0

Xin lỗi vì phản hồi rất muộn, hãy sử dụng AOP cho các phương thức cần đồng bộ hóa giao dịch –

Các vấn đề liên quan