Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use AsyncLocalStorage for transaction context support #13889

Closed
2 tasks done
ajwootto opened this issue Sep 22, 2023 · 2 comments
Closed
2 tasks done

Use AsyncLocalStorage for transaction context support #13889

ajwootto opened this issue Sep 22, 2023 · 2 comments
Labels
enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature new feature This change adds new functionality, like a new method or class
Milestone

Comments

@ajwootto
Copy link

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the feature has not already been requested

🚀 Feature Proposal

A few other ORMs use the NodeJS AsyncLocalStorage API to provide a more ergonomic way of using transactions. One example is Sequelize: https://sequelize.org/docs/v7/querying/transactions/#disabling-cls

Basically this allows someone to write a bunch of business logic that might span several different function calls etc. while having all the ORM database calls automatically use a transaction that was started earlier in the callstack, without having to pass an object like session around and manually provide it to each ORM call.

I think this would be a pretty powerful alternative interface for transactions

Motivation

We are writing an API where we have a use-case that requires us to start a transaction at the beginning of every request and then use it for each DB operation that occurs within that request's business logic, before committing the transaction at the end.

Currently that requires us to find our own way to pass the session object around, eg:

async function requestHandler() {
  await connection.withTransaction(async (session) => {
     await someBusinessLogic(session)
 
  }
}

async function someBusinessLogic(session) {
 // need to explicitly provide session
  MyModel.findOneAndUpdate({}, {}, {session})
}

but with this proposal you wouldn't need to provide the session:

async function requestHandler() {
  await connection.withTransactionContext(async (session) => {
     await someBusinessLogic()
 
  }
}

async function someBusinessLogic() {
 // automatically uses transaction by finding it via AsyncLocalStorage context provided by `withTransactionContext` wrapper
   MyModel.findOneAndUpdate({}, {})
}

Example

No response

@ajwootto ajwootto added enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature new feature This change adds new functionality, like a new method or class labels Sep 22, 2023
@vkarpov15 vkarpov15 added this to the 7.x Unprioritized milestone Oct 1, 2023
@vkarpov15
Copy link
Collaborator

This is a good suggestion, we will investigate how we can support this.

@vkarpov15 vkarpov15 modified the milestones: 7.x Unprioritized, 8.3, 8.4 Mar 13, 2024
vkarpov15 added a commit that referenced this issue May 10, 2024
…cally setting `session` on all transactions

Fix #13889
vkarpov15 added a commit that referenced this issue May 15, 2024
feat: add `transactionAsyncLocalStorage` option to opt in to automatically setting `session` on all transactions
@vkarpov15 vkarpov15 reopened this Jul 5, 2024
@vkarpov15 vkarpov15 modified the milestones: 8.4, 7.8.0 Jul 5, 2024
vkarpov15 added a commit that referenced this issue Jul 11, 2024
…lly setting session on all transactions

Backport #14583 to 7.x
Re: #13889
vkarpov15 added a commit that referenced this issue Jul 19, 2024
feat: add transactionAsyncLocalStorage option to opt in to automatically setting session on all transactions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature new feature This change adds new functionality, like a new method or class
Projects
None yet
Development

No branches or pull requests

3 participants