gpt4 book ai didi

java - 如何在 Java 中同步并发的 Web 服务调用

转载 作者:行者123 更新时间:2023-11-30 11:34:38 24 4
gpt4 key购买 nike

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

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

它们被正确触发,当它们被单独调用时,CreateBlogEntryCreateComment 绝对没有问题。

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

所以我有两个选择:

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

目前我正在尝试前者,但是一旦这两个服务都完全执行,我最终会得到两个 BlogEntries。其中一个只有 CreateCommentForUpcomingBlogEntry 提供的 ID,但它已正确连接到 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 hibernate 几秒钟,但我认为这不是正确的做法。

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

那么:让它等待 BlogEntry 存在的最佳做法是什么?

提前致谢,大卫

信息:

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

最佳答案

如果您确定收到 CreateBlogEntry 调用,请将 CreateCommentForUpcomingBlogEntry 调用排队,并在收到 CreateBlogEntry 调用后出列并处理它们.

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

关于java - 如何在 Java 中同步并发的 Web 服务调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15551977/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com