繁体   English   中英

使用Web服务时避免多次呼叫

[英]Avoiding multiple calls when consuming a web service

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

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

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

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

谢谢

您需要做的就是创建一个单独的组件,该组件负责从第三方获取XML并将其保存到数据库中。
在您的代码中,各种线程尝试从该组件中“获取” XML
该组件从数据库返回XML (如果存在)。 如果不存在,则使用ReentrantLock进行同步。
因此,您进行了一次trylock ,只有一个线程成功。 其余的将被阻止。 释放锁后,其他线程将被解除阻塞,但XML已从第三方获取并由首先设法获得锁的线程存储到数据库中。 因此,其他线程仅从数据库返回XML

示例代码(。这仅仅是一个“伪代码”,让你开始你应该处理异常等,但可使用的主骨架不要忘记unlockfinally让你的代码不indefinitelly BLOCK):

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;  
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM