是否可以使用Azure表存储进行条件插入

Mar*_*ann 7 etag azure optimistic-concurrency event-sourcing azure-table-storage

是否可以使用Windows Azure表存储服务进行条件插入

基本上,我想要做的是将新的行/实体插入到表存储服务的分区中,当且仅当我上次查看时该分区中没有任何更改.

如果您想知道,我会考虑事件采购,但我认为问题比这更普遍.

基本上我想阅读部分或整个分区,并根据数据内容做出决定.为了确保自加载数据后分区中没有任何更改,插入应该像普通的乐观并发一样:只有在分区中没有任何更改的情况下插入才会成功 - 没有添加,更新或删除任何行.

通常在REST服务中,我希望使用ETag来控制并发性,但据我所知,分区没有ETag.

我能想到的最好的解决方案是为表中的每个分区维护一个单行/实体,其中包含一个时间戳/ ETag,然后使所有插入包含一个由插入组成的批处理以及这个'的条件更新'时间戳实体'.然而,这听起来有点麻烦和脆弱.

Azure表存储服务可以实现吗?

Yve*_*out 4

从千英尺看去的景色

我可以与您分享一个小故事吗?

曾几何时,有人想要将事件持久化(来自领域驱动设计名声)以响应给定的命令。此人希望确保聚合仅创建一次,并且可以检测到任何形式的乐观并发。

为了解决第一个问题(聚合只能创建一次),他在事务介质中进行了插入,当检测到重复聚合(或更准确地说是其主键)时,该插入会抛出异常。他插入的是作为主键的聚合标识符和变更集的唯一标识符。此处所说的变更集是在处理命令时由聚合产生的事件集合。如果有人或其他事比他先一步,他会考虑已经创建的聚合并保留它。变更集将预先存储在他选择的介质中。该媒介必须做出的唯一承诺是在被要求时按原样返回已存储的内容。任何存储变更集的失败都将被视为整个操作的失败。

为了解决第二个问题 - 在聚合的进一步生命周期中检测乐观并发 - 在编写另一个变更集之后,当且仅当没有人在他背后更新它时,他才会更新事务介质中的聚合记录(即与他在执行命令之前最后读取的内容进行比较)。如果发生这样的事情,交易媒介会通知他。这将导致他重新启动整个操作,重新读取聚合(或其变更集)以使命令这次成功。

当然,现在他解决了写作问题,随之而来的是阅读问题。人们如何能够读取构成其历史的聚合的所有变更集?毕竟,他只有与该事务介质中的聚合标识符相关联的最后提交的变更集。因此,他决定嵌入一些元数据作为每个变更集的一部分。在元数据中(作为变更集的一部分并不罕见)将是先前最后提交的变更集的标识符。这样,他就可以“沿着”聚合的变更集“走线”,就像一个链接列表一样。

作为额外的好处,他还将命令消息标识符存储为变更集元数据的一部分。这样,当读取变更集时,他可以提前知道他要在聚合上执行的命令是否已经是其历史记录的一部分。

一切都好,结局好...

PS
1. 事务介质和变更集存储介质可以相同,
2. 变更集标识符不能是命令标识符,
3. 请随意在故事中打孔:-),
4. 虽然与 Azure 表没有直接关系存储,我已经使用 AWS DynamoDB 和 AWS S3 成功实现了上述故事。