2

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

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

它们被正确触发,并且当它们被单独调用时绝对没有CreateBlogEntry问题CreateComment

但是:服务CreateCommentForUpcomingBlogEntry会发送Comment一个“外键”来识别“即将到来的” BlogEntry。在内部,它还调用CreateBlogEntry创建实际的BlogEntry. 由于它们的异步特性,这两个服务是并发的。

所以我有两个选择:

  1. 创建一个虚拟对象BlogEntry并将其连接Comment到它并更新BlogEntry, 一旦CreateBlogEntry“到达”
  2. 等待CreateBlogEntry并将Comment之后连接到新的BlogEntry

目前我正在尝试前者,但一旦两个服务都完全执行,我最终会得到两个 BlogEntries. 其中一个只有ID交付,CreateCommentForUpcomingBlogEntry但它正确连接到Comment(更多相反)。otherBlogEntry具有所有其他信息(例如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 服务器 3.1.2
  • EclipseLink,版本:Eclipse Persistence Services - 2.3.2.v20111125-r10461
4

1 回答 1

1

如果您确定自己CreateBlogEntry接到电话,请在接到电话后将电话排队CreateCommentForUpcomingBlogEntry并出列并处理它们CreateBlogEntry

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

于 2013-03-21T18:34:34.800 回答