Как использовать многодокументные ACID транзакции MongoDB 4.0 с Meteor 1.8 - PullRequest
0 голосов
/ 13 февраля 2019

Пытался сделать это следующим образом: https://github.com/meteor/meteor/blob/3051150f2f5ae953f391802e73682fba613b3d46/packages/mongo/mongo_livedata_tests.js#L3431-L3487

, но получал много ошибок, таких как:

UnhandledPromiseRejectionWarning: MongoError: Данная транзакция номер 5 не соответствует ни одной из выполняемых транзакций.

Я использую следующий код:

collection.js содержит следующую вспомогательную функцию для переноса команд db в транзакциях в других местах (это все на стороне сервера):

const { client } = MongoInternals.defaultRemoteCollectionDriver().mongo;

export const RunInMongoTx = async function(func) {
      try {
        const session = await client.startSession();
        session.startTransaction();
        options = { session };

        func(options);

        session.commitTransaction();
      } catch (error) {
        session.abortTransaction();
        throw error;
      }
    };

В других файлах я затем импортирую функцию и использую ее:

import {RunInMongoTx} from "./collections";

Meteor.methods({
  "ShiftRequests.setAsDidNotTurnUp": sr => {
    const job = Jobs.findOne({ _id: sr.jobId });
    if (job.poster != Meteor.userId()) {
      throw new Meteor.Error(
        "not-job-poster",
        "Only poster can setAsDidNotTurnUp"
      );
    }

    RunInMongoTx(async options => {
      res = await EmployerFeedbacks.rawCollection().remove(
        {
          jobId: job._id,
          workerId: sr.workerId
        },
        options
      );

      res = await ShiftRequests.rawCollection().update(
        { _id: sr._id },
        { $set: { didNotTurnUp: true } },
        options
      );
    });
  }
});

1 Ответ

0 голосов
/ 13 февраля 2019

Я думаю, что ваша проблема в том, что вы вызываете функцию RunInMongoTx без ожидания.

const { client } = MongoInternals.defaultRemoteCollectionDriver().mongo;

export const RunInMongoTx = async function(func) {
      try {
        const session = await client.startSession();
        session.startTransaction();
        options = { session };

        await func(options);

        session.commitTransaction();
      } catch (error) {
        session.abortTransaction();
        throw error;
      }
    };
import {RunInMongoTx} from "./collections";

Meteor.methods({
  "ShiftRequests.setAsDidNotTurnUp": async sr => {
    const job = Jobs.findOne({ _id: sr.jobId });
    if (job.poster != Meteor.userId()) {
      throw new Meteor.Error(
        "not-job-poster",
        "Only poster can setAsDidNotTurnUp"
      );
    }

    await RunInMongoTx(async options => {
      res = await EmployerFeedbacks.rawCollection().remove(
        {
          jobId: job._id,
          workerId: sr.workerId
        },
        options
      );

      res = await ShiftRequests.rawCollection().update(
        { _id: sr._id },
        { $set: { didNotTurnUp: true } },
        options
      );
    });
  }
});

Дайте мне знать, если это сработало.

...