Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用web服务时避免多次调用_Java_Web Services - Fatal编程技术网

Java 使用web服务时避免多次调用

Java 使用web服务时避免多次调用,java,web-services,Java,Web Services,我有一个任务,用户使用来自第三方的XML。XML提要每天只更新一次。XML存储在数据库中,并在用户请求时返回给用户。如果XML不在数据库中,则从第三方检索它,存储在数据库中并返回给用户。所有后续请求都将从数据库中读取XML 现在我的问题。假设向第三方返回请求需要10秒钟。在此期间,对同一数据有多个服务器调用。我不希望这些都向第三方发出请求,也不希望用户收到任何信息或错误。他们可能应该等待第一个请求完成,此时XML将可用。这是一个相对简单的问题,但我想知道最好的解决方法是什么 我是否只是使用一个简

我有一个任务,用户使用来自第三方的XML。XML提要每天只更新一次。XML存储在数据库中,并在用户请求时返回给用户。如果XML不在数据库中,则从第三方检索它,存储在数据库中并返回给用户。所有后续请求都将从数据库中读取XML

现在我的问题。假设向第三方返回请求需要10秒钟。在此期间,对同一数据有多个服务器调用。我不希望这些都向第三方发出请求,也不希望用户收到任何信息或错误。他们可能应该等待第一个请求完成,此时XML将可用。这是一个相对简单的问题,但我想知道最好的解决方法是什么

我是否只是使用一个简单的标志来控制请求,或者像信号灯这样的东西?是否有更好的解决方案基于我打算使用的堆栈,即Play框架和cassandra后端。我可以用回调或触发器做些什么吗

顺便说一下,当第一个请求传入时,我需要延迟加载数据。因此,在这个任务中,不能选择在单独的进程中或在应用程序启动时获取数据


谢谢

您只需创建一个单独的组件,负责从第三方获取
XML
,并将其保存到数据库中。
在您的代码中,各个线程尝试从该组件“获取”XML 此组件从数据库返回
XML
(如果存在)。如果它不存在,则您可以使用进行同步。
因此,您执行了一个任务,但只有一个线程成功。其余部分将被封锁。当锁被释放时,其他线程被解锁,但是
XML
已经从第三方获取,并由第一个设法获得锁的线程存储到数据库中。因此,其他线程只是从数据库返回
XML

示例代码(这只是一个开始的“伪代码”。您应该处理异常等,但可以使用主框架。在
最后
中不要忘记
解锁
,这样代码就不会不确定地阻塞):


使用锁似乎是一个非常简单和不错的解决方案。您也可以“同步”从第三方检索数据的方法,并管理一个简单的布尔标志“isLoadingFromThirdParty”。在10秒钟的更新窗口内,您是否真的会收到对同一数据的多个请求?这会造成什么危害?您是否会通过后续调用数据来显著降低处理速度?我这样问是因为开发人员往往在不明确需求的情况下过度设计。有人为此付出了代价,他们实际上可能更愿意花钱购买一个基本的工作产品,在过度担心性能问题和效率之前,他们可以把它放在客户面前。我完全同意。这更像是一项技术任务。如果由我决定,我甚至不会在一开始就懒得加载数据。要求是,如果大量用户同时访问站点,则第三方端点不可能受到攻击-尽管我同意这是过度工程化的做法,但答案取决于您的部署架构。如果您针对多个类加载器运行应用程序,无论它们是在同一jvm(即应用程序服务器)、企业环境(集群和实时故障切换)中,还是部署到云上,都会产生很大的不同。如果您在单个类加载器中,那么您可以简单地实现一个单例业务外观,该外观可以从db或同步方法中的服务获取信息。如果您在一个多类加载器环境中,那么问题就更难解决了。@EngineerDollery在一个水平扩展的应用程序中,假设只有一个数据库,您是否可以设置嵌套的事务传播级别-将状态提交到数据库-“从远程数据库获取数据”呢。
public String getXML() {  
  String xml = getXMLFromDatabase();  
  if(xml == null) {  
     if(glocalLock.tryLock()) {  
        try{  
            xml = getXMLFromThirdParty();  
            storeXMLToDatabase(xml);       
        }  
        finally {  
            globalLock.unlock(); //ok! got XML and stored in DB. Wake-up others!  
        }  
     }
    else {  
         try{ //Another thread got the lock and will do the query. Just wait on lock!     
             globalLock.lock();  
         }  
         finally {
             //woken up but the xml is already fetched  
             xml = getXMLFromDatabase();  
             globalLock.unlock();  
         }   
     }    
  return xml;  
}