6

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

基本上是两个问题。

  1. 更新没有发生有时没有,错误消息。
  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 />";
  }
}

乐观并发的更新函数是这里的主要测试。

4

2 回答 2

0

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

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

根据此处的文档:

如果实体的 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 的原因。在updateEntity它被设置为true而在insertOrReplaceEntity它被设置为false

于 2013-06-09T18:51:49.030 回答
0

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

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

如果您在同一实体上每秒执行 1 次读取、写入操作,它将在没有 Etag 失败的情况下工作。否则,您已经围绕此构建了自己的智能逻辑。

另一个有用的资源是:

如何在 Azure 中构建高度可扩展的全局计数器?

于 2013-06-24T11:22:29.420 回答