事务性批处理波斯菊-如果在分区中读取某些值则写入

问题描述

在波斯菊中使用事务处理批处理,是否可以查询集合(Select * from partition where openorder=1)中的分区,然后如果查询返回没有未结订单,则向集合中添加项目。

或者您可以先进行写入,然后进行条件读取(Select * from partition where openorder=1 and id={unique GUID just written}),然后如果第二次读取失败,则写入将被反转(?)。

我希望在一个原子操作中完成此操作,因为我不想认为没有未结订单,然后另一个进程会在此流程之前写一个未结订单。

如果没有,是否可以以其他方式执行此操作?

**编辑下午3:30 PT 9/16时使用尝试的解决方案,该解决方案在我测试时写了一份文件**

function checkOpenorder(inputDocString,query){
    console.log("Stored Procedure Starting")
    var context = getContext(); 
    var container = context.getCollection();
    var containerLink = container.getSelfLink();
    var response = context.getResponse(); 

    var isAccepted = container.queryDocuments(
        container.getSelfLink(),query,function (err,items,options) {
            if (err) throw err;
            // Query would be fed in such that if there is no open order,no items would return in the collection 

            if (items.length == 0){ 
                var docCreated = container.createDocument(containerLink,inputDocString,function (err2,itemWritten) {
                        if (err2) throw err2;
                        // else was successfully able to write document?
                        response.setBody("Wrote document");
                    });

            }
            else { 
               
                response.setBody("Order currently open");
            }
            

        });
    if (!isAccepted) throw new Error('The query was not accepted by the server.')

    
}

编辑:最终问题9/17 我是否要将最大并行度设置为1,以确保存储过程不能在同一分区中同时运行2次? (如果看到没有未结订单,可能会创建竞争条件->创建一个文档,然后我们有2个未结订单)。我认为我想禁用跨分区查询(再也不需要它)。

enter image description here

解决方法

恐怕答案是否定的。 TransactionalBatch仅支持写操作。如果您要进行跨文档的读写事务,则只有两种选择:

  1. 在存储过程中执行事务。仅当您在单个分区中工作并且您不需要在事务内执行任何与Cosmos不相关的操作时,此方法才有效。根据您的描述,应该可以。

  2. 使用某种锁定在客户端执行事务。

,

如答案之一所述,TransactionBatch仅支持写操作。我们在Cosmos DB中也面临过类似的挑战。解决问题的方法如下:

  • 您可以引入“会话”的概念,其中在请求/会话结束时进行提交/保存操作。
  • 为所有Get操作创建本地身份映射/缓存。也就是说,首先检查Cosmos文档是否在本地缓存中,如果是,则从本地缓存返回它。否则,请从Cosmos获取。
  • CreateUpsertDelete操作仅保存到本地缓存并更新身份映射。
  • Commit操作在请求结束时被调用。它使用本地缓存中的项目创建一个事务批并将其保存到Cosmos。

这种方法的优点是,您可以使用C#完成所有这些操作,而无需任何复杂的锁定代码。

此方法的一些局限性是:

  • 它只能在单个分区内工作(我认为这对您来说很好)
  • 由于您正在使用Cosmos Document的ID,因此传递自定义QueryDefinition不适用于ids可能很棘手。