如何在Java中同步同步Web Service调用

时间:2013-03-21 15:41:55

标签: java web-services jpa persistence

我目前正在开发一些由SAP系统触发的Java(带有MySQL连接的JPA)Web服务。 为了简化我的问题,我将两个关键实体称为BlogEntryCommentBlogEntry可以有多个CommentsComment始终属于一个BlogEntry

所以我有三个服务(我不能也不想重新定义,因为它们是由我从SAP导出并用于并行与其他系统通信的WSDL定义的):CreateBlogEntryCreateCommentCreateCommentForUpcomingBlogEntry

它们被正确触发,CreateBlogEntryCreateComment在单独调用时完全没有问题。

但是:服务CreateCommentForUpcomingBlogEntry发送Comment和“外键”以识别“即将推出的”BlogEntry。在内部,它还会调用CreateBlogEntry来创建实际的BlogEntry这两项服务由于其异步性质而同意。

所以我有两个选择:

  1. 创建一个虚拟BlogEntry并将Comment连接到它&一旦BlogEntry“到达”
  2. ,请更新CreateBlogEntry
  3. 等待CreateBlogEntry然后将Comment关联到新的BlogEntry
  4. 目前我正在尝试,但是一旦两项服务都完全执行,我最终会使用两个 BlogEntries。其中一个只有IDCreateCommentForUpcomingBlogEntry传递,但它已正确连接到Comment(反之亦然)。其他BlogEntry包含所有其他信息(例如postDatebody),但Comment未与其相关。


    以下是服务实现CreateCommentForUpcomingBlogEntry的代码段:

    @EJB
    private BlogEntryFacade blogEntryFacade;
    @EJB
    private CommentFacade commentFacade;
    ...
    List<BlogEntry> blogEntries = blogEntryFacade.findById(request.getComment().getBlogEntryId().getValue());
    BlogEntry persistBlogEntry;
    if (blogEntries.isEmpty()) {
        persistBlogEntry = new BlogEntry();
        persistBlogEntry.setId(request.getComment().getBlogEntryId().getValue());
        blogEntryFacade.create(persistBlogEntry);
    } else {
        persistBlogEntry = blogEntries.get(0);
    }
    
    Comment persistComment = new Comment();
    persistComment.setId(request.getComment().getID().getValue());
    persistComment.setBody(request.getComment().getBody().getValue());
    /*
        set other properties
    */
    persistComment.setBlogEntry(persistBlogEntry);
    commentFacade.create(persistComment);
    ...
    

    以下是实施CreateBlogEntry的代码段:

    @EJB
    private BlogEntryFacade blogEntryFacade;
    ...
    List<BlogEntry> blogEntries = blogEntryFacade.findById(request.getBlogEntry().getId().getValue());
    BlogEntry persistBlogEntry;
    Boolean update = false;
    if (blogEntries.isEmpty()) {
        persistBlogEntry = new BlogEntry();
    } else {
        persistBlogEntry = blogEntries.get(0);
        update = true;
    }
    persistBlogEntry.setId(request.getBlogEntry().getId().getValue());
    persistBlogEntry.setBody(request.getBlogEntry().getBody().getValue());
    /*
        set other properties
    */
    if (update) {
        blogEntryFacade.edit(persistBlogEntry);
    } else {
        blogEntryFacade.create(persistBlogEntry);
    }
    ...
    

    这是一些无法让事情按照假设发生的小事。

    遗憾的是,我还没有找到同步这些同时服务调用的方法。我可以让CreateCommentForUpcomingBlogEntry 睡觉几秒钟,但我不认为这是正确的方法。

    我可以强制facades及其各自EntityManagers的每个实例重新加载数据集吗?我可以根据某些条件将我的请求放在某种正在清空的队列中吗?

    那么:等待BlogEntry存在的最佳实践是什么?

    提前致谢, 大卫

    的信息:

    • GlassFish Server 3.1.2
    • EclipseLink,版本:Eclipse Persistence Services - 2.3.2.v20111125-r10461

1 个答案:

答案 0 :(得分:1)

如果您确定收到了CreateBlogEntry来电,请排好CreateCommentForUpcomingBlogEntry个来电,并在收到CreateBlogEntry来电后出列并处理。

由于您在应用程序服务器上,对于队列,您可以使用自动刷新存储的JMS队列或使用数据库缓存引擎(Ehcache?),以防您收到大量呼叫或想要提供恢复机制重启。