Azure表更新并发问题

Mar*_*ark 6 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.

我正在使用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 />";
  }
}
Run Code Online (Sandbox Code Playgroud)

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

Gau*_*tri 0

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

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

基于此处的文档:

如果实体的 ETag 与更新请求中指定的 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
        );
    }
Run Code Online (Sandbox Code Playgroud)

注意两个函数中的第四个参数。这是强制使用 ETag 的原因。在updateEntity它被设置为true时,在insertOrReplaceEntity它被设置为false