并行执行DocumentDb存储过程 [英] Executing DocumentDb stored procedures in parallel

查看:25
本文介绍了并行执行DocumentDb存储过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

DocentDb存储过程是否可以并行运行并更新同一对象?DocentDb是否会按顺序处理它们?

请考虑以下方案。

我有一个应用程序,当我的用户完成一项任务时,我有10000枚硬币可以赠送给他们。我有以下对象

{
    remainingPoints: 10000
}

我有一个存储过程,它从此对象中减去10个点,然后将它们添加到用户的点上。

现在假设有10个用户同时完成任务,我同时调用存储过程10次,DocDb会按顺序执行它们吗?还是必须按顺序执行存储过程?

推荐答案

我第一次开始使用DocumentDB时也有类似的问题,在这里和DocumentDB产品经理的电子邮件中都得到了很好的回答。报价:

存储过程.获取数据库的隔离快照以提供事务支持。快照反映存储过程开始执行时的当前状态(无陈旧数据)(高度一致)。

警告-由于存储过程是在快照上操作的,因此如果在执行过程中从外部传入新的写入,您仍然可以在存储过程中获得过时的读取。

另外,存储过程将始终读取其自己的写入。

Sprocs是DocumentDB用于多文档事务的机制。存储过程写入在存储过程成功完成执行时提交。如果引发异常,存储过程中完成的所有工作都将回滚。

因此,如果两个存储过程同时运行,它们将看不到对方的写入。

如果两个sprocs碰巧写入同一文档(替换),则第二个sprocs在尝试提交写入时将由于ETag不匹配而失败。

由此,我继续我的设计,确保按照@Julian建议的那样在写作中使用eTag。我还会自动重试每次存储过程执行最多3次,以处理由于并行操作等原因而失败的情况。在实践中,我从未超过3次重试(除非我的存储过程有错误),我甚至很少得到一次重试。

根据我观察到的行为,我假设它会将每个新的存储过程执行发送到不同的副本,直到它用完副本,然后将它们排队等待顺序执行,因此这是并行和串行执行的混合。

我通过实验学到的另一个技巧是,当您在负载较重的系统上时,最好在客户端执行纯读取操作(没有写入,也没有重大聚合),而不是在存储过程中执行。我认为其优势是因为DocumentDB可以并行满足来自不同副本的不同读取。我已经使用documentdb-utilsexpandScript功能模块化了我的存储过程代码,以确保我对客户端和服务器端的编写验证、文档内一致性和派生字段使用完全相同的代码,这在使用node.js时是可能的。即使您主要使用.NET,您也可能希望使用expandScripts以模块化的干式方式构建您的sprocs。您仍然需要在构建过程中运行node.js来预处理您的存储过程,或者使用Edge.NET(在.NET内部运行的节点)在飞翔上执行此操作。

这篇关于并行执行DocumentDb存储过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆