Azure表更新并发问题

时间:2013-06-09 16:24:23

标签: azure azure-storage azure-storage-blobs azure-table-storage

我正在尝试针对每笔交易更新用户信用/计数信息。如果我们每秒达到超过2/4的交易,则下面的更新不会更新计数/用户信用信息。

基本上有两个问题。

  1. 使用NO,错误消息,有时不会发生更新。
  2. 更新失败并显示错误消息:412:失败:代码:412值:前提条件失败详细信息(如果有):UpdateConditionNotSatisfied不满足请求中指定的更新条件。 RequestId:1beb3fa9-9ad2-46f7-b8ee-af3a09300db7时间:2013-06-09T16:12:17.6797130Z。
  3. 我正在使用Azure为SMS API做一个从RDMBS迁移到NoSQL的原型。不知道为什么会发生这样的事情。

    下面的代码粘贴

    public function update_credit_to_azure_table () {
      // Create table REST proxy.
      $tableRestProxy = ServicesBuilder::getInstance()
        ->createTableService($this->connectionString);
    
      $result = $tableRestProxy->getEntity("tblapilogin",  $this->apiusr , $this->apiusr);
      $entity = $result->getEntity();
    
      $new_api_balance = $this->global_api_credit - $this->credittodeduct;
      $credit_used = $this->api_credit_used + $this->credittodeduct;
    
      $entity->setPropertyValue("global_api_credit", $new_api_balance); //Update Balance.
      $entity->setPropertyValue("api_credit_used", $credit_used); //credit used Updated .
    
      try {
        $tableRestProxy->updateEntity("tblapilogin", $entity);
    
        echo "<br>New Blance is: " . $new_api_balance;
        echo "<br>credit_used  is: " . $credit_used;
      }
      catch(ServiceException $e) {
        $code = $e->getCode();
        $error_message = $e->getMessage();
        echo $code.": ".$error_message."<br />";
      }
    }
    

    具有乐观并发性的更新函数在这里是一种主要的测试。

2 个答案:

答案 0 :(得分:0)

我不是PHP的专家,但查看Github上的源代码,我发现updateEntity函数总是强制使用ETag,即函数强制条件更新:

public function updateEntity($table, $entity, $options = null)
    {
        return $this->_putOrMergeEntityImpl(
            $table,
            $entity,
            Resources::HTTP_PUT,
            true, 
            $options
        );
    }

基于文档here

  

如果实体的ETag与更新指定的不同   请求,更新操作失败,状态码为412(前提条件   失败)。此错误表示实体已更改   服务器,因为它被检索。要解决此错误,请检索   实体再次重新发出请求。

     

要强制进行无条件更新操作,请设置值   If-Match标头到请求上的通配符(*)。通过   该操作的值将覆盖默认的乐观   并发并忽略ETag值中的任何不匹配。

如果Etag值不匹配,您将收到412错误。

我建议使用insertOrReplaceEntity操作而不是updateEntity操作,因为它会创建一个实体,如果它不存在,否则它会更新它。另外看一下代码,这个代码没有使用ETag

public function insertOrReplaceEntity($table, $entity, $options = null)
    {
        return $this->_putOrMergeEntityImpl(
            $table,
            $entity,
            Resources::HTTP_PUT,
            false, 
            $options
        );
    }

注意两个函数中的第4个参数。这是强制使用ETag的那个。在updateEntitytrue设置为insertOrReplaceEntityfalse设置为{{1}}。

答案 1 :(得分:0)

与史蒂夫在他的一集中解释的问题相同。

http://channel9.msdn.com/Shows/Cloud+Cover/Cloud-Cover-Episode-43-Scalable-Counters-with-Windows-Azure

如果您在同一实体上每秒执行1次读取,写入操作,则无法使用Etag failuer。否则你就会围绕这个构建自己的智能逻辑。

另一个有用的资源是:

How to build a highly scaleable global counter in Azure?