- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 3.9k
Closed
Closed
Copy link
Labels
confirmed-bugWe've confirmed this is a bug in Mongoose and will fix it.We've confirmed this is a bug in Mongoose and will fix it.
Milestone
Description
Prerequisites
- I have written a descriptive issue title
- I have searched existing issues to ensure the bug has not already been reported
Mongoose version
8.4.0
Node.js version
20.15.0
MongoDB server version
6
Typescript version (if applicable)
No response
Description
The new transactionAsyncLocalStorage mechanism seems to work great for individual operations like save and create on models. It doesn't seem to be honored on bulk operations such as insertMany.
Steps to Reproduce
Forgive the slightly convoluted code here, we have a wrapper over mongoose models with some singleton logic for working in AWS Lambda.
This test passes as I'd expect:
it.only('supports transactions without explicitly passing the session object', async () => {
  mongoose.set('transactionAsyncLocalStorage', true);
  await ChildDao.instance.find({ filter: {}, context }); // just forcing a preflight to get a connection, ignore
  await ChildDao.instance.model.db
    .transaction(async () => {
      await ChildDao.instance.model.create({ name: 'test' });
      throw new Error('Rollback');
    })
    .catch(() => {});
  expect(await ChildDao.instance.model.findOne({ name: 'test' })).toBeNull();
});
This test fails:
it.only('supports transactions without explicitly passing the session object', async () => {
  mongoose.set('transactionAsyncLocalStorage', true);
  await ChildDao.instance.find({ filter: {}, context });
  await ChildDao.instance.model.db
    .transaction(async () => {
      await ChildDao.instance.model.insertMany([{ name: 'test' }]);
      throw new Error('Rollback');
    })
    .catch(() => {});
  expect(await ChildDao.instance.model.findOne({ name: 'test' })).toBeNull();
});
This test passes, explicitly passing the session:
it.only('supports transactions on bulk operations if explicitly passed a session', async () => {
  mongoose.set('transactionAsyncLocalStorage', true);
  await ChildDao.instance.find({ filter: {}, context });
  await ChildDao.instance.model.db
    .transaction(async (session) => {
      await ChildDao.instance.model.insertMany([{ name: 'test' }], { session });
      throw new Error('Rollback');
    })
    .catch(() => {});
  expect(await ChildDao.instance.model.findOne({ name: 'test' })).toBeNull();
});
Expected Behavior
The transactionAsyncLocalStorage should allow the more ergonomic flow for bulk operations as well. This might fall under a feature request, but without the caveats explained in the docs I'd be inclined to call it a bug.
Metadata
Metadata
Assignees
Labels
confirmed-bugWe've confirmed this is a bug in Mongoose and will fix it.We've confirmed this is a bug in Mongoose and will fix it.