将对象更新到 Azure 表存储 - 有没有办法获取新的时间戳?

发布于 2024-10-28 03:12:30 字数 232 浏览 6 评论 0原文

我正在使用 StorageClient 库更新 AzureTableStorage 中的对象,

    context.UpdateObject(obj);
    context.SaveChangesWithRetries(obj);

当我执行此操作时,是否有任何方法可以获取 obj 的新时间戳,而无需向服务器发出另一个请求?

谢谢斯图尔特

I'm updating an object in AzureTableStorage using the StorageClient library with

    context.UpdateObject(obj);
    context.SaveChangesWithRetries(obj);

when I do this, is there any way to get hold of the new timestamp for obj without making another request to the server?

Thanks

Stuart

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

安穩 2024-11-04 03:12:30

补充一下 Seva Titov 的回答:报告的摘录至少在 2013 年 5 月之前有效,但截至 2013 年 11 月它已经发生了变化(添加了强调):

Timestamp 属性是一个在服务器端维护的 DateTime 值,用于记录实体上次修改的时间。表服务在内部使用 Timestamp 属性来提供开放式并发。 Timestamp 的值是单调递增的值,这意味着每次修改实体时,该实体的 Timestamp 值都会增加。不应在插入或更新操作时设置此属性(该值将被忽略)。

现在,Timestamp 属性不再被视为不透明,并且记录表明其值在每次操作后都会增加编辑——这表明时间戳现在可以用于跟踪后续更新(至少对于单个实体而言)。

尽管如此,截至 2013 年 11 月,当您更新实体时,仍然需要向表存储发出另一个请求才能获取新的时间戳(请参阅 更新实体 REST 方法)。仅当插入实体时,REST 服务才会返回整个实体时间戳(但我不记得这是否是由 StorageClient/Windows Azure 存储库公开的)。

To supplement Seva Titov's answer: the excerpt reported was valid at least until May 2013, but as of November 2013 it has changed (emphasis added):

The Timestamp property is a DateTime value that is maintained on the server side to record the time an entity was last modified. The Table service uses the Timestamp property internally to provide optimistic concurrency. The value of Timestamp is a monotonically increasing value, meaning that each time the entity is modified, the value of Timestamp increases for that entity. This property should not be set on insert or update operations (the value will be ignored).

Now the Timestamp property is no longer regarded as opaque and it is documented that its value increases after each edit -- this suggests that could Timestamp could be now used to track subsequent updates (at least with regard to the single entity).

Nevertheless, as of November 2013 it is still needed another request to Table Storage to obtain the new timestamp when you update the entity (see the documentation of Update Entity REST method). Only when inserting an entity the REST service returns the entire entity with the timestamp (but I don't remember if this is exposed by the StorageClient/Windows Azure storage library).

病女 2024-11-04 03:12:30

MSDN 页面有一些关于 Timestamp 字段使用的指导:

时间戳属性

Timestamp 属性是 DateTime
服务器上维护的值
记录实体存在的时间
最后修改。表服务使用
Timestamp 属性内部为
提供乐观并发。
应该将此属性视为不透明:
不应读取或设置它
插入或更新操作(值
将被忽略)。

这意味着它实际上是表存储的实现细节,您不应该依赖 Timestamp 字段来表示上次更新的时间戳。

如果您想要一个保证代表上次写入时间的字段,请创建新字段并在每个更新操作上设置它。我知道维护该字段需要更多工作(和更多存储空间),但这实际上会自动解决您的问题 - 如何取回时间戳,因为您在调用 context.UpdateObject() 时已经知道它了。

MSDN page has some guidance on the usage of Timestamp field:

Timestamp Property

The Timestamp property is a DateTime
value that is maintained on the server
side to record the time an entity was
last modified. The Table service uses
the Timestamp property internally to
provide optimistic concurrency. You
should treat this property as opaque:
It should not be read, nor set on
insert or update operations (the value
will be ignored).

This implies that it is really implementation details of the table storage, you should not rely the Timestamp field to represent timestamp of last update.

If you want a field which is guaranteed to represent time of last write, create new field and set it on every update operatio. I understand this is more work (and more storage space) to maintain the field, but that would actually automatically resolves your question -- how to get the timestamp back, because you would already know it when calling context.UpdateObject().

揽清风入怀 2024-11-04 03:12:30

Timestamp 属性实际上是一个 Lamport 时间戳。它保证总是随着时间的推移而增长,虽然它以 DateTime 值的形式呈现,但实际上并非如此。

在服务器端,即 Windows Azure 存储,每次更改都会执行以下操作:

nextTimestamp = Math.Max(currentTimestamp + 1, DateTime.UtcNow)

这就是它的全部内容。当然,这肯定会以交易方式发生。所有这一切的目的是提供一个逻辑时钟(单调函数),可用于确保事件的顺序按预期顺序发生。

这是实际WAS论文<的链接/a> 虽然它不包含任何有关时间戳方案的信息,但它有足够的内容,您很快就会意识到从中只能得出一个逻辑结论。任何其他的事情都是愚蠢的。另外,如果您有使用 LevelDB、Cassandra、Memtables 等的经验,您会发现 WAS 团队走了同样的路。

不过我应该补充说明一下,由于 WAS 提供了强一致性模型,维护时间戳的唯一方法是在锁定和密钥下进行,因此您无法猜测正确的下一个时间戳。您必须查询 WAS 来获取信息。没有办法解决这个问题。然而,您可以保留旧值并假设它没有改变。 WAS 会告诉您是否存在,然后您可以以您认为合适的任何方式解决竞争条件。

The Timestamp property is actually a Lamport timestamp. It is guaranteed to always grow over time and while it is presented as a DateTime value it's really not.

On the server side, that is, Windows Azure Storage, for each change does this:

nextTimestamp = Math.Max(currentTimestamp + 1, DateTime.UtcNow)

This is all there is to it. And it's of course guaranteed to happen in a transactional manner. The point of all this is to provide a logical clock (monotonic function) that can be used to ensure that the order of events happen in the intended order.

Here's a link to a version of the actual WAS paper and while it doesn't contain any information on the timestamp scheme specifically it has enough stuff there that you quickly realize that there's only one logical conclusion you can draw from this. Anything else would be stupid. Also, if you have any experience with LevelDB, Cassandra, Memtables and it's ilk, you'll see that the WAS team went the same route.

Though I should add to clarify, since WAS provides a strong consistency model, the only way to maintain the timestamp is to do it under lock and key, so there's no way you can guess the correct next timestamp. You have to query WAS for the information. There's no way around that. You can however hold on to an old value and presume that it didn't change. WAS will tell you if it did and then you can resolve the race condition any way you see fit.

无声无音无过去 2024-11-04 03:12:30

我使用的是 Windows Azure Storage 7.0.0

您可以查看操作结果获取 eTagTimespan 属性:

var tableResult = cloudTable.Execute(TableOperation.Replace(entity));
var updatedEntity = tableResult.Result as ITableEntity;

var eTag = updatedEntity.ETag;
var timestamp = updatedEntity.Timestamp;

I am using Windows Azure Storage 7.0.0

And you can check the result of the operation to get the eTag and the Timespan properties :

var tableResult = cloudTable.Execute(TableOperation.Replace(entity));
var updatedEntity = tableResult.Result as ITableEntity;

var eTag = updatedEntity.ETag;
var timestamp = updatedEntity.Timestamp;
原野 2024-11-04 03:12:30

我不这么认为,据我所知Timespan和Etag是由Azure Storage本身设置的。

I don't think so, as far as I know Timespan and Etag are set by Azure Storage itself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文