Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 即使mongodb中的一个事务发生错误,事务也不会中止?_Javascript_Node.js_Mongodb_Mongoose_Transactions - Fatal编程技术网

Javascript 即使mongodb中的一个事务发生错误,事务也不会中止?

Javascript 即使mongodb中的一个事务发生错误,事务也不会中止?,javascript,node.js,mongodb,mongoose,transactions,Javascript,Node.js,Mongodb,Mongoose,Transactions,每当一个事务失败时,它也不会中止该事务,并且事务得到部分提交。例如:当我使用邮递员发送错误的注册号时,Publisher.findoneandUpdate返回“TypeError:无法读取null的属性“$session”,事务应该中止,但它得到了部分提交,就像Publisher行上方的代码一样,将其保存在文档中。 我正在使用mongodb atlas我对您的问题的理解是,当事务中抛出错误时,事务不会中止 在检查代码时,您似乎将async/wait与承诺混合在一起,这导致代码可读性降低,而且工作

每当一个事务失败时,它也不会中止该事务,并且事务得到部分提交。例如:当我使用邮递员发送错误的注册号时,Publisher.findoneandUpdate返回“TypeError:无法读取null的属性“$session”,事务应该中止,但它得到了部分提交,就像Publisher行上方的代码一样,将其保存在文档中。
我正在使用mongodb atlas

我对您的问题的理解是,当事务中抛出错误时,事务不会中止

在检查代码时,您似乎将async/wait与承诺混合在一起,这导致代码可读性降低,而且工作方式也略有不同

使用async/await时,任何
return
语句都将导致承诺解析而不是拒绝,而使用
throw
语句时,承诺将被拒绝而不是解析

现在,您可以使用
.catch
捕获回调中抛出的任何错误,但是,如果该方法因为
$session
null
上不存在而抛出,则不会调用您的
(等待会话)。abortTransaction()

但是,如果使用try/catch/finally,则不会执行
catch
finally
,因为不会抛出错误。您已经在回拨中发现任何错误

相反,使用async/await,看看是否有什么不同(请原谅自动格式化代码):

请注意:我还没有对此进行测试,但是,请尝试一下,看看您的问题是否已得到纠正。如果
abortTransaction
endSession
是异步的,则根据需要使用wait

router.put('/', async (req, res) => {
    try {
    const today = new Date();
    var month = (today.getMonth()) + 1;
    var year = today.getFullYear();
    var field = year + "-" + month;
    var category = req.body.category;
    var date = today.getDate();
    const session =  mongoose.startSession();
    const transactionOptions = {
        readPreference: 'primary',
        readConcern: { level: 'local' },
        writeConcern: { w: 'majority' }
    };
   
        const news = await News.findById(req.body.id);
        var newsDate = new Date(news.createdAt).getDate();
        var newsMonth = new Date(news.createdAt).getMonth() + 1;
        var newsYear = new Date(news.createdAt).getFullYear();
        // (await session).startTransaction();


        // (await Publisher.findOneAndUpdate({ registrationNumber: req.body.registrationNumber }, { $inc: { [`monthlyViews.${field}`]: 1, [`categoriesViews.${category}`]: 1 } })).$session(session);
        // if (newsDate == date && newsMonth == month && newsYear == year) {
        //     (await News.findOneAndUpdate({ _id: req.body.id }, { $inc: { [`views.${field}`]: 1, [`totalViews`]: 1, ['publishedDateViews']: 1 } })).$session(session);
        // } else {
        //     (await News.findOneAndUpdate({ _id: req.body.id }, { $inc: { [`views.${field}`]: 1, [`totalViews`]: 1 } })).$session(session);
        // }

        // (await session).commitTransaction();
        // res.status(200).send({ status: 1 });
        const transactionResult = (await session).withTransaction(async () => {
            
            var newsResult;
            if (newsDate == date && newsMonth == month && newsYear == year) {
                newsResult = (await News.findOneAndUpdate({ _id: req.body.id }, { $inc: { [`views.${field}`]: 1, [`totalViews`]: 1, ['publishedDateViews']: 1 } })).$session(session);
            } else {
                newsResult = (await News.findOneAndUpdate({ _id: req.body.id }, { $inc: { [`views.${field}`]: 1, [`totalViews`]: 1 } })).$session(session);
            }
            if (!newsResult) {
                return (await session).abortTransaction();

            }
            const pubresult = (await Publisher.findOneAndUpdate({ registrationNumber: req.body.registrationNumber }, { $inc: { [`monthlyViews.${field}`]: 1, [`categoriesViews.${category}`]: 1 } })).$session(session);
            if (!pubresult) {
                return (await session).abortTransaction();

            }



        }, transactionOptions).then(result => { res.status(200).send({ status: 1 }); }).catch(e => {
            console.log(e);
            res.status(400).send({ status: 0 });

        });
    } catch (error) {
        // (await session).abortTransaction();
        console.error(error);
        res.status(500).send({ status: 0, message: "Internal Server error" });
    } finally {
        (await session).endSession();
    }


});

router.put('/', async (req, res) => {
  try {
    const today = new Date();
    var month = today.getMonth() + 1;
    var year = today.getFullYear();
    var field = year + '-' + month;
    var category = req.body.category;
    var date = today.getDate();
    const session = await mongoose.startSession(); // await here
    const transactionOptions = {
      readPreference: 'primary',
      readConcern: { level: 'local' },
      writeConcern: { w: 'majority' },
    };

    const news = await News.findById(req.body.id);
    var newsDate = new Date(news.createdAt).getDate();
    var newsMonth = new Date(news.createdAt).getMonth() + 1;
    var newsYear = new Date(news.createdAt).getFullYear();
    // (await session).startTransaction();

    // (await Publisher.findOneAndUpdate({ registrationNumber: req.body.registrationNumber }, { $inc: { [`monthlyViews.${field}`]: 1, [`categoriesViews.${category}`]: 1 } })).$session(session);
    // if (newsDate == date && newsMonth == month && newsYear == year) {
    //     (await News.findOneAndUpdate({ _id: req.body.id }, { $inc: { [`views.${field}`]: 1, [`totalViews`]: 1, ['publishedDateViews']: 1 } })).$session(session);
    // } else {
    //     (await News.findOneAndUpdate({ _id: req.body.id }, { $inc: { [`views.${field}`]: 1, [`totalViews`]: 1 } })).$session(session);
    // }

    // (await session).commitTransaction();
    // res.status(200).send({ status: 1 });
    await session.withTransaction(async () => {
      var newsResult;
      // if you haven't already, learn about strict equality
      if (newsDate == date && newsMonth == month && newsYear == year) {
        newsResult = (
          await News.findOneAndUpdate(
            { _id: req.body.id },
            {
              $inc: {
                [`views.${field}`]: 1,
                [`totalViews`]: 1,
                ['publishedDateViews']: 1,
              },
            }
          )
        ).$session(session);
      } else {
        newsResult = (
          await News.findOneAndUpdate(
            { _id: req.body.id },
            { $inc: { [`views.${field}`]: 1, [`totalViews`]: 1 } }
          )
        ).$session(session);
      }
      if (!newsResult) {
        // if not found, catch {} will catch it
        throw new Error('news result does not exist');
      }
      const pubresult = (
        await Publisher.findOneAndUpdate(
          { registrationNumber: req.body.registrationNumber },
          {
            $inc: {
              [`monthlyViews.${field}`]: 1,
              [`categoriesViews.${category}`]: 1,
            },
          }
        )
      ).$session(session);
      if (!pubresult) {
        throw new Error('publisher does not exist');
      }
    }, transactionOptions);

    res.status(200).send({ status: 1 });
  } catch (error) {
    session.abortTransaction(); // await if async

    if (
      error.message === 'publisher does not exist' ||
      error.message === 'news result does not exist'
    ) {
      res.status(404).send({ status: 0 }); // not found
      return;
    }
    // handle validation errors or whatever you used 400 for
    res.status(500).send({ status: 0, message: 'Internal Server error' });
  } finally {
    session.endSession();
  }
});