2

我正在 Windows Azure 网站 (IISNode) 上开发 node.js 应用程序,并为 node.js 安装了 Azure SDK 模块。我的问题是如何在表存储中使用 etag 或时间戳字段。

是否是“我”做某事的问题,例如:

if (entities[0].Timestamp == newEntity.Timestamp)
    // commit this update because we are dealing with the latest copy of this entity
else
    // oops! one of the entities is newer than the other, better not save it

或者我是否需要侦听 tableService.updateEntity( ... 返回的错误或其他错误?

任何帮助或建议表示赞赏

4

2 回答 2

4

ETag 用于更新期间的乐观并发。ETag 在您检索实体时自动设置,并在您更新该查询实体时自动上传。如果实体同时已被另一个线程更新,则更新将失败。updateEntity 方法有一个可选参数 checkEtag,可用于修改此行为,方法是允许您指定更新应该成功,而不管其他线程是否更新了记录 - 从而覆盖乐观并发。

Windows Azure 存储服务 REST API 是 Windows Azure 存储的权威接口,htis 是您想要了解该服务的 API 功能时可以参考的文档。一般来说,描述 ETag 的文档在这里

于 2012-09-13T05:27:01.410 回答
3

正如尼尔所说,好的做法是让表服务处理与并发相关的东西。

当我们使用客户端库从表服务中获取实体时,库会将与实体关联的 ETag(存在于实体的服务响应中)存储在 EntityDescriptior 实例中(EntityDescriptor 是由库维护的对象,用于上下文中的每个实体实例)

当您提交更新实体的请求时,sdk 将准备 HTTP 请求,主体为序列化为 XML 的实体,请求的 ETag 标头为存储在实体对应的实体描述符中的 ETag 值。

当表服务接收到这个更新实体实例的请求时,它会检查请求中的 ETag 是否与表存储中当前与实体关联的 ETag 匹配(如果发生其他更新,则与存储在服务中的实体关联的 ETag 会更改)在收到您的更新请求之前),如果不匹配,则通过在 412 或 409 的响应中设置 Http 状态代码,服务返回前置条件失败/冲突错误。

bool done = true;
while (!done)
{
    Stat statistics = _context.Execute<Stat>(new Uri("https://management.core.windows.net/<subscription-id>/services/storageservices/StatEntity?RowKey=..&PartitionKey=..").FirstOrDefault();

    try
    {
        // TODO: Update the entity, e.g. statistics.ReadCount++
        _context.UpdateObject(statistics);
        _context.SaveChanges();
        // success
        break;
    }
    catch (DataServiceRequestException exception)
    {
        var response = exception.Response.FirstOrDefault();
        if (response != null && (response.StatusCode == 412 || response.StatusCode == 409))
        {
            // Concurrency Exception - Entity Updated in-between
            // by another thread, Fetch the latest _stat entity and repeat operation
        }
        else
        {
            // log it and come out of while loop
            break;
        }
    }
    catch (Exception)
    {
        // log it and come out of while loop
        break;
    }
}
于 2012-09-13T05:37:39.883 回答