且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

并行执行DocumentDb存储过程

更新时间:2023-02-15 10:08:27

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

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

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

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

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

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

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

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

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

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