General node.js/javascript问题和事件循环
我有以下问题: 我让两个函数写入我的数据库。在将它们插入数据库之前,我会检查是否存在类似的项:General node.js/javascript问题和事件循环,javascript,node.js,
elasticsearch,event-loop,Javascript,Node.js,
elasticsearch,Event Loop,我有以下问题: 我让两个函数写入我的数据库。在将它们插入数据库之前,我会检查是否存在类似的项: const storeListing = async listing => { //Some logic const foundSimilar = await findSimilar(listing); if(!foundSimilar){ await insertListing(listing) }else{ //Perform duplicate che
const storeListing = async listing => {
//Some logic
const foundSimilar = await findSimilar(listing);
if(!foundSimilar){
await insertListing(listing)
}else{
//Perform duplicate check
if(foundSimilar.buildingType===listing.buildingType){
console.log('found')
}
}
}
现在,当我做以下工作时:
const test = () => {
storeListing({buildingType:'MFH'});
storeListing({buildingType:'MFH'});
}
带有重复检查的else条件永远不会触发
我的想法是这两个函数按顺序处理(事件循环)。因此,在完成一个操作之前,不能再次调用storeListing
那么,我在这里是否有一个逻辑问题,或者仅仅是数据库具有最终的一致性
编辑: 当我不知道有多少其他函数调用storeListing并且我希望它序列化时(例如,我有多户住宅的storeListing-单户住宅的storeListing) 这是一个好的模式:
const lock={};
export const storeListing = async (listing, type) => {
const id= uuidv1();
while (Object.keys(lock).length>0){
await timeout(15);
}
threadLock[id]=true;
//Function like above
delete lock[id];
}
即使插入顺序不相关,您仍然需要使用
wait
,以避免竞争条件
完整代码将以下I/O操作排入队列:
findSimilar
调用都在其中一个insertListing
完成之前完成,所以它们都不返回匹配项
您应该使用async
,如下所示:
let test = async () => {
await storeListing({ buildingType:'MFH' });
await storeListing({ buildingType:'MFH' });
};
这对操作顺序实施了一个新的限制:在测试中,2必须出现在3之前。您的not
WAIT
ing。在这种情况下,顺序无关紧要-项目类似。因此,如果插入一个,则第二个将类似,反之亦然。我只是在这里发表了一条评论——这里仍然有逻辑,但为了更好地概述,将其省略了;)但我现在让代码更清楚了:)这看起来像是一个数据库竞争条件,因为您同时有两个查询,它们不会被序列化。当您调用本机代码接口(如数据库)时,本机代码上可能没有任何单线程、事件循环驱动的限制。无法以这种方式编程到本机代码接口。您必须向我们展示findSimilar()
的实际代码,以便我们了解建议内容,但您通常需要了解数据库的并发管理功能。仅供参考,发布一个仅包含伪代码的问题意味着我们无法给您任何具体建议,只能提供伪建议。这里的正确解决方案取决于实际的代码、使用的数据存储类型及其接口。在这里提问时,请张贴真实代码。您将得到更多更有价值的建议,而且通常会更快,而不会有太多来回的问题。这通常是解决数据库并发性问题的错误方法。对于这样的问题,数据库具有内置的并发特性,而这些问题没有像这样的所有限制。另外,在事件驱动系统中轮询锁是一种非常糟糕的设计。你会有一堆锁处于挂起和活动状态,你的CPU会花很多时间轮询锁。更不用说,你没有一个“公平”的系统来决定谁下一个去,因为这是随机的。无法使用群集。无法防止其他进程访问数据库等等……或者可能storeListing
被认为可以正确执行事务,而bug就在那里。从这个问题上我不清楚要求是什么。这可能是一个更好的建议!我更喜欢在DB层看到“buildingType”(或任何构成“相似性”的东西)的唯一性。是的,我发现我的问题不够尖锐。对此我很抱歉。但所有这些建议都对我有所帮助