javascript - Multi-Document Transactions not Working using MongoDB Atlas - Stack Overflow

UPDATEAfter some suggestions I modifies the code like this:const session = await mongoose.startSession(

UPDATE

After some suggestions I modifies the code like this:

const session = await mongoose.startSession()
session.startTransaction()
try {
    const udpated = await Schema1.findByIdAndUpdate(
        'id', { $set: { /* ... */ } }, { session }
    )
    const array = await Promise.all(
        updated.array.map(async item => {
            // change 1
            const doc = await Schema2.findById(item.someId).session(session)
            const payload = { /* ... */ }
            // change 2
            return new Schema3(payload).save({ session })
        })
    )
    await sessionmitTransaction()
    session.endSession()
} catch (err) {
    await session.abortTransaction()
    session.endSession()
    throw err
}

But that gives me another error:

{
    MongoError: internal atlas error checking things: Failure getting dbStats: read tcp 192.168.254.116:52242->192.168.254.116:27000: i/o timeout
    at /some-path/node_modules/mongodb-core/lib/connection/pool.js:581:63
    at authenticateStragglers (/some-path/node_modules/mongodb-core/lib/connection/pool.js:504:16)
    at Connection.messageHandler (/some-path/node_modules/mongodb-core/lib/connection/pool.js:540:5)
    at emitMessageHandler (/some-path/node_modules/mongodb-core/lib/connection/connection.js:310:10)
    at TLSSocket.<anonymous> (/some-path/node_modules/mongodb-core/lib/connection/connection.js:453:17)
    at emitOne (events.js:116:13)
    at TLSSocket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    at TLSSocket.Readable.push (_stream_readable.js:208:10)
    at TLSWrap.onread (net.js:597:20)
  ok: 0,
  errmsg: 'internal atlas error checking things: Failure getting dbStats: read tcp 192.168.254.116:52242->192.168.254.116:27000: i/o timeout',
  code: 8000,
  codeName: 'AtlasError',
  name: 'MongoError',
  [Symbol(mongoErrorContextSymbol)]: {} }
× Unexpected error occured MongoError: internal atlas error checking things: Failure getting dbStats: read tcp 192.168.254.116:52242->192.168.254.116:27000: i/o timeout
    at /some-path/node_modules/mongodb-core/lib/connection/pool.js:581:63
    at authenticateStragglers (/some-path/node_modules/mongodb-core/lib/connection/pool.js:504:16)
    at Connection.messageHandler (/some-path/node_modules/mongodb-core/lib/connection/pool.js:540:5)
    at emitMessageHandler (/some-path/node_modules/mongodb-core/lib/connection/connection.js:310:10)
    at TLSSocket.<anonymous> (/some-path/node_modules/mongodb-core/lib/connection/connection.js:453:17)
    at emitOne (events.js:116:13)
    at TLSSocket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    at TLSSocket.Readable.push (_stream_readable.js:208:10)
    at TLSWrap.onread (net.js:597:20)

Btw.: I also refactored that code without using mongoose (I just used the standard mongodb client for nodejs and I am still getting those errors.


I am using mongoose transactions because of my problem referred to in this question.

However, my problem is, that my implementation of Promise.all() doesn't seem to work with mongoose transactions. The issue probably es from using multiple Schemas with one session or creating an array of documents. (But I am really not sure)

const session = await mongoose.startSession()
session.startTransaction()
try {
    const udpated = await Schema1.findByIdAndUpdate(
        'id', { $set: { /* ... */ } }, { session }
    )
    const array = await Promise.all(
        updated.array.map(async item => {
            const doc = await Schema2.findById(item.someId)
            const payload = { /* ... */ }
            return Schema3.createa(payload, { session })
        })
    )
    await sessionmitTransaction()
    session.endSession()
} catch (err) {
    await session.abortTransaction()
    session.endSession()
    throw err
}

I am getting errors, that the validation of Schema3 failed for some required paths. Even though payload is found when console.log it.

{ ValidationError: xxx validation failed: xxx: Path `xxx` is required., xxx: Path `xxx` is required., xxx: Path `xxx` is required.
    at ValidationError.inspect (/xxx/node_modules/mongoose/lib/error/validation.js:59:24)
    at formatValue (util.js:400:38)
    at inspect (util.js:294:10)
    at format (util.js:223:18)
    at Console.log (console.js:130:21)
    at module.exports (xxx.js:228:17)
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:228:7)
  errors:
   { xxx:
      { ValidatorError: Path `xxx` is required.
    at new ValidatorError (/xxx/node_modules/mongoose/lib/error/validator.js:29:11)
    at validate (/xxx/node_modules/mongoose/lib/schematype.js:871:13)
    at /xxx/node_modules/mongoose/lib/schematype.js:924:11
    at Array.forEach (<anonymous>)
    at SchemaString.SchemaType.doValidate (/xxx/node_modules/mongoose/lib/schematype.js:880:19)
    at /xxx/node_modules/mongoose/lib/document.js:1913:9
    at _binedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickDomainCallback (internal/process/next_tick.js:218:9)
        message: 'Path `xxx` is required.',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'xxx',
        value: undefined,
        reason: undefined,
        [Symbol(mongoose:validatorError)]: true },
     xxx:
      { ValidatorError: Path `xxx` is required.
    at new ValidatorError (/xxx/node_modules/mongoose/lib/error/validator.js:29:11)
    at validate (/xxx/node_modules/mongoose/lib/schematype.js:871:13)
    at /xxx/node_modules/mongoose/lib/schematype.js:924:11
    at Array.forEach (<anonymous>)
    at ObjectId.SchemaType.doValidate (/xxx/node_modules/mongoose/lib/schematype.js:880:19)
    at /xxx/node_modules/mongoose/lib/document.js:1913:9
    at _binedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickDomainCallback (internal/process/next_tick.js:218:9)
        message: 'Path `xxx` is required.',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'xxx',
        value: undefined,
        reason: undefined,
        [Symbol(mongoose:validatorError)]: true },
     xxx:
      { ValidatorError: Path `xxx` is required.
    at new ValidatorError (/xxx/node_modules/mongoose/lib/error/validator.js:29:11)
    at validate (/xxx/node_modules/mongoose/lib/schematype.js:871:13)
    at /xxx/node_modules/mongoose/lib/schematype.js:924:11
    at Array.forEach (<anonymous>)
    at ObjectId.SchemaType.doValidate (/xxx/node_modules/mongoose/lib/schematype.js:880:19)
    at /xxx/node_modules/mongoose/lib/document.js:1913:9
    at _binedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickDomainCallback (internal/process/next_tick.js:218:9)
        message: 'Path `xxx` is required.',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'xxx',
        value: undefined,
        reason: undefined,
        [Symbol(mongoose:validatorError)]: true } },
  _message: 'xxx validation failed',
  name: 'ValidationError' }

When refactoring the code without using mongoose transactions, everything works just fine:

try {
    const udpated = await Schema1.findByIdAndUpdate(
        'id', { $set: { /* ... */ } }
    )
    const array = await Promise.all(
        updated.array.map(async item => {
            const doc = await Schema2.findById(item.someId)
            const payload = { /* ... */ }
            return Schema3.createa(payload)
        })
    )
} catch (err) {
    throw err
}

UPDATE

After some suggestions I modifies the code like this:

const session = await mongoose.startSession()
session.startTransaction()
try {
    const udpated = await Schema1.findByIdAndUpdate(
        'id', { $set: { /* ... */ } }, { session }
    )
    const array = await Promise.all(
        updated.array.map(async item => {
            // change 1
            const doc = await Schema2.findById(item.someId).session(session)
            const payload = { /* ... */ }
            // change 2
            return new Schema3(payload).save({ session })
        })
    )
    await session.mitTransaction()
    session.endSession()
} catch (err) {
    await session.abortTransaction()
    session.endSession()
    throw err
}

But that gives me another error:

{
    MongoError: internal atlas error checking things: Failure getting dbStats: read tcp 192.168.254.116:52242->192.168.254.116:27000: i/o timeout
    at /some-path/node_modules/mongodb-core/lib/connection/pool.js:581:63
    at authenticateStragglers (/some-path/node_modules/mongodb-core/lib/connection/pool.js:504:16)
    at Connection.messageHandler (/some-path/node_modules/mongodb-core/lib/connection/pool.js:540:5)
    at emitMessageHandler (/some-path/node_modules/mongodb-core/lib/connection/connection.js:310:10)
    at TLSSocket.<anonymous> (/some-path/node_modules/mongodb-core/lib/connection/connection.js:453:17)
    at emitOne (events.js:116:13)
    at TLSSocket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    at TLSSocket.Readable.push (_stream_readable.js:208:10)
    at TLSWrap.onread (net.js:597:20)
  ok: 0,
  errmsg: 'internal atlas error checking things: Failure getting dbStats: read tcp 192.168.254.116:52242->192.168.254.116:27000: i/o timeout',
  code: 8000,
  codeName: 'AtlasError',
  name: 'MongoError',
  [Symbol(mongoErrorContextSymbol)]: {} }
× Unexpected error occured MongoError: internal atlas error checking things: Failure getting dbStats: read tcp 192.168.254.116:52242->192.168.254.116:27000: i/o timeout
    at /some-path/node_modules/mongodb-core/lib/connection/pool.js:581:63
    at authenticateStragglers (/some-path/node_modules/mongodb-core/lib/connection/pool.js:504:16)
    at Connection.messageHandler (/some-path/node_modules/mongodb-core/lib/connection/pool.js:540:5)
    at emitMessageHandler (/some-path/node_modules/mongodb-core/lib/connection/connection.js:310:10)
    at TLSSocket.<anonymous> (/some-path/node_modules/mongodb-core/lib/connection/connection.js:453:17)
    at emitOne (events.js:116:13)
    at TLSSocket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    at TLSSocket.Readable.push (_stream_readable.js:208:10)
    at TLSWrap.onread (net.js:597:20)

Btw.: I also refactored that code without using mongoose (I just used the standard mongodb client for nodejs and I am still getting those errors.


I am using mongoose transactions because of my problem referred to in this question.

However, my problem is, that my implementation of Promise.all() doesn't seem to work with mongoose transactions. The issue probably es from using multiple Schemas with one session or creating an array of documents. (But I am really not sure)

const session = await mongoose.startSession()
session.startTransaction()
try {
    const udpated = await Schema1.findByIdAndUpdate(
        'id', { $set: { /* ... */ } }, { session }
    )
    const array = await Promise.all(
        updated.array.map(async item => {
            const doc = await Schema2.findById(item.someId)
            const payload = { /* ... */ }
            return Schema3.createa(payload, { session })
        })
    )
    await session.mitTransaction()
    session.endSession()
} catch (err) {
    await session.abortTransaction()
    session.endSession()
    throw err
}

I am getting errors, that the validation of Schema3 failed for some required paths. Even though payload is found when console.log it.

{ ValidationError: xxx validation failed: xxx: Path `xxx` is required., xxx: Path `xxx` is required., xxx: Path `xxx` is required.
    at ValidationError.inspect (/xxx/node_modules/mongoose/lib/error/validation.js:59:24)
    at formatValue (util.js:400:38)
    at inspect (util.js:294:10)
    at format (util.js:223:18)
    at Console.log (console.js:130:21)
    at module.exports (xxx.js:228:17)
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:228:7)
  errors:
   { xxx:
      { ValidatorError: Path `xxx` is required.
    at new ValidatorError (/xxx/node_modules/mongoose/lib/error/validator.js:29:11)
    at validate (/xxx/node_modules/mongoose/lib/schematype.js:871:13)
    at /xxx/node_modules/mongoose/lib/schematype.js:924:11
    at Array.forEach (<anonymous>)
    at SchemaString.SchemaType.doValidate (/xxx/node_modules/mongoose/lib/schematype.js:880:19)
    at /xxx/node_modules/mongoose/lib/document.js:1913:9
    at _binedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickDomainCallback (internal/process/next_tick.js:218:9)
        message: 'Path `xxx` is required.',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'xxx',
        value: undefined,
        reason: undefined,
        [Symbol(mongoose:validatorError)]: true },
     xxx:
      { ValidatorError: Path `xxx` is required.
    at new ValidatorError (/xxx/node_modules/mongoose/lib/error/validator.js:29:11)
    at validate (/xxx/node_modules/mongoose/lib/schematype.js:871:13)
    at /xxx/node_modules/mongoose/lib/schematype.js:924:11
    at Array.forEach (<anonymous>)
    at ObjectId.SchemaType.doValidate (/xxx/node_modules/mongoose/lib/schematype.js:880:19)
    at /xxx/node_modules/mongoose/lib/document.js:1913:9
    at _binedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickDomainCallback (internal/process/next_tick.js:218:9)
        message: 'Path `xxx` is required.',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'xxx',
        value: undefined,
        reason: undefined,
        [Symbol(mongoose:validatorError)]: true },
     xxx:
      { ValidatorError: Path `xxx` is required.
    at new ValidatorError (/xxx/node_modules/mongoose/lib/error/validator.js:29:11)
    at validate (/xxx/node_modules/mongoose/lib/schematype.js:871:13)
    at /xxx/node_modules/mongoose/lib/schematype.js:924:11
    at Array.forEach (<anonymous>)
    at ObjectId.SchemaType.doValidate (/xxx/node_modules/mongoose/lib/schematype.js:880:19)
    at /xxx/node_modules/mongoose/lib/document.js:1913:9
    at _binedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickDomainCallback (internal/process/next_tick.js:218:9)
        message: 'Path `xxx` is required.',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'xxx',
        value: undefined,
        reason: undefined,
        [Symbol(mongoose:validatorError)]: true } },
  _message: 'xxx validation failed',
  name: 'ValidationError' }

When refactoring the code without using mongoose transactions, everything works just fine:

try {
    const udpated = await Schema1.findByIdAndUpdate(
        'id', { $set: { /* ... */ } }
    )
    const array = await Promise.all(
        updated.array.map(async item => {
            const doc = await Schema2.findById(item.someId)
            const payload = { /* ... */ }
            return Schema3.createa(payload)
        })
    )
} catch (err) {
    throw err
}
Share Improve this question edited Jan 6, 2019 at 6:15 Florian Ludewig asked Jan 2, 2019 at 9:17 Florian LudewigFlorian Ludewig 6,03216 gold badges83 silver badges156 bronze badges 8
  • I believe that if you use Promise.all you don't need async/await inside the map function. Try to remove it. – Sagi Rika Commented Jan 2, 2019 at 9:51
  • Did not work :-( – Florian Ludewig Commented Jan 2, 2019 at 9:59
  • is createa an async function? or only find by id? – Sagi Rika Commented Jan 2, 2019 at 10:00
  • create returns a Promise – Florian Ludewig Commented Jan 2, 2019 at 10:02
  • 1 I have version 4. I contacted the support and it's a known problem that will be fixed with version 4.0.5. Thank you anyways :) – Florian Ludewig Commented Jan 9, 2019 at 8:28
 |  Show 3 more ments

4 Answers 4

Reset to default 6

I contacted the MongoDB Support and it turned out that this is a known issue:

We are currently aware of an issue with the M0 Free Tier clusters whereby multi-statement transactions timeout with an error. This should be fixed with the rollout of MongoDB version 4.0.5. In the meantime, if you require this feature urgently, I would remend that you upgrade your cluster to an M10+ cluster.

So the issue occurs because I am using the free tier. But the bug will hopefully be fixed with the MongoDB 4.0.5 release.

UPDATE

As my database runs now on version 4.0.5, the problem is fixed. So it wasn't necessarily a issue with the code.

Try adding .session(session) to each Query

const doc = await Schema2.findById(item.someId).session(session)

https://mongoosejs./docs/api.html#query_Query-session

Looks like you're missing a session option in findOne():

const doc = await Schema2.findById(item.someId, null, { session })

See: https://mongoosejs./docs/api.html#model_Model.findOne

I had a similar problem, i created a document in a session, then i used the ._id, created from other document "B", and then find the first document with other property, when the first document, i pushed that B in the first document, the solutions that i try was using multiples session.startTransaction();

example:

session.startTransaction();

create first document

 await session.mitTransaction();
 session.startTransaction();

create second document, search the first document with other property with which it was created, and push this B._id into the first document and then updated this first document

await session.mitTransaction();

and for the end session.endSession()

I realized this when i did a console.log(first document) when i search it again and push b into them, just i think, its like a mit in the cluster? so maybe with other session works... and it worked

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1743762110a4502821.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信