在MongoDB中保持并发读取操作的一致性

时间:2019-08-19 08:15:40

标签: node.js mongodb express mongoose mongodb-query

我在Node.js中有一个API,说/create/appointment可以进行2次操作

步骤1:检查数据库中的活动约会。

第2步:创建约会(如果不存在)。

我有3个收藏

  1. doctors
  2. patients
  3. appointments

约会集合有3个主要字段

doctor_id:MongoDb对象ID patient_id:MongoDB对象ID is_active:布尔值

STEP 1包含一个DB读取操作。 STEP 2包含一个DB写操作。 当API同时触发多次时, 在第一周期的步骤2完成之前执行第二周期的步骤1。由于第一个循环的STEP 2未完成,因此第二个循环的STEP 1不会返回在第一个循环中创建的活动约会条目。

  

我不能在以下位置使用复合唯一索引:

     
      
  1. {doctor_id, patient_id},因为appointment集合可以包含历史数据。

  2.   
  3. {doctor_id, patient_id, is_active},那么appointment集合只能包含一个无效条目。

  4.   

实施:

// All functions below return promise object.
doctorManager
.getDoctor(doctor_id)
.then(doctor => {
  // throw error if doctor does not exist
  return patientManager.getPatient(patient_id);
})
.then(patient => {
  // throw error if patient does not exist
  return getActiveAppointment(doctor_id, patient_id)
})
.then(activeAppointment => {
  // throw error if active appointment exist
  return appointmentManager.createAppointment(doctor_id, patient_id)  
})
.then(() => {
  // return API response
})
.catch(error => {
  // handel error
});

在进行任何类型的操作或任何其他更好的解决方案时,是否可以锁定appointment集合。 我无法分片数据库,也无法设置复制。

1 个答案:

答案 0 :(得分:0)

当您使用异步等待功能时,将显示以下内容。它不是问题解决方案,而只是正确处理问题的一个示例。

ofstream outfile;
outfile.open ("entries.txt");
 for (/*for loop for each entry*/) {
    std::stringstream ss;
    //assign input values to ss per entry 
    boost::property_tree::ptree pt;
    boost::property_tree::read_json(ss, pt);
    std::string IP = pt.get<std::string>("ip");
    std::string PORT = pt.get<std::string>("ports.port");
    outfile << IP << ":" <<PORT;
}