2015-10-17 45 views
0

在我的應用程序的用戶創建它獲取在DB堅持+發佈到春天AMQP隊列同步Hibernate持久+春AMQP發佈交易

後當用戶創建一個帖子流撞擊控制器

@RequestMapping(value="/createPost", method=RequestMethod.POST, consumes = "application/json", 
      produces = "application/json") 
    public @ResponseBody Post createUserPost(@RequestBody(required=false) Post post, Principal principal){ 
     this.userService.persistPost(post); 
     logger.info("post persistance successful"); 
     publishService.publishUserPosts(post); 
     return post; 
    } 

有兩種服務persistPost & publishUserPosts在控制器中調用的不同服務類。

發佈服務

@Transactional 
    public void publishUserPosts(Post post){ 
     try{ 
      logger.info("Sending user post to the subscribers"); 
      amqpTemplate.convertAndSend(post); 
      }catch(AmqpException e){ 
       throw new MyAppException(e); 
      } 
    } 

問題既是服務呼叫在不同的交易運行。如果PublishPost事務失敗,則該帖子仍然保留在數據庫中。

要將這兩個服務都帶到一個單獨的事務中,我已經更改了代碼&在PublishPost類中注入了persistPost服務。

@Transactional 
    public void publishUserPosts(Post post){ 
     try{ 
      userService.persistPost(post); 
      logger.info("post persistance successful"); 
      logger.info("Sending user post to the subscribers"); 
      amqpTemplate.convertAndSend(post); 
      }catch(AmqpException e){ 
       throw new MyAppException(e); 
      } 
    } 

我的問題

這是下單成交,實現多種業務,最好的辦法還是可以用一些其他的方法做的更好?

+0

可以肯定的是,您使用的是JTA嗎?否則,您用來發送消息的事務並不是真的在做任何事情。 – Augusto

+0

我正在使用HibernateTransactionManager。我測試了代碼,交易工作正常,只需要確認方法。 – underdog

回答

1

我認爲你對交易的工作原理感到困惑。 HiberanteTransactionManager只能處理數據庫操作。爲了使其他部分也是事務性的,例如消息傳遞,您必須使用稱爲Java Transactional API(JTA)的技術,它允許將合併不同技術的事務合併成一個大的分佈式事務。在春季,這由JTATransactionManage提供。

無論如何,在這種情況下更受歡迎的設計(如果您遵循域驅動設計模式)將有一個Application Service作爲您的域的外觀,並負責保持事務邊界。然後,該應用程序服務調用Post Repository(您稱爲userService)並最終發佈消息。所以在僞代碼

class PostApplicationService { 
    @Transactional 
    public void publishUserPosts(Post post){ 
     postRepository.save(post); 
     publishService.notifyNewPost(post); 
    } 
} 

而且我會使用本地事件總線(如春季或番石榴提供的)做通知。但那只是我的偏好:)。

+0

感謝Augusto的回覆,我按照Spring AMQP文檔實現了事務,RabbitMQ不支持分佈式事務。因此,我正在使用hibernate事務管理器遵循最佳效果1PC單階段提交模式。我甚至檢查過日誌,消息發送者和偵聽器容器被HibernateTransactionManager覆蓋。按照文檔@Transactional正常工作,只需要一個支持事務的渠道。此外,我正在考慮使用服務器發送的事件向瀏覽器發送新帖子的通知。 – underdog