MongoDB Transactions #11737
Replies: 8 comments 43 replies
-
Using the async/await solution suggested in the forums, one can get: Meteor.methods({
'some.method.name'(itemId: string, smurfId: string) {
return executeTransaction(async () => {
const smurf = await Smurfs.rawCollection().findOne(
{_id: smurfId},
{session},
);
if (!smurf) {
throw new Meteor.Error('not-found');
}
const meta = await Items.rawCollection().updateOne(
{_id: itemId},
{
$pull: {'meta.y': smurfId},
},
{session},
);
...
});
},
}); Reactivity still works, although maybe lag is larger, Meteor is able to pickup changes from Mongo's oplog (correct?). One can even throw in specific transaction options or session options if needed. What's annoying is that one has to pass the PS: I personally prefer try/catch and surf the async vibe: "example3_purchaseItem": async function (purchaseData) {
try {
const { invoiceId } = await Mongo.Transaction(async () => {
const invoiceId = await Invoice.insert({...purchaseData});
const changeQuantity = await Items.update(purchaseData.itemId, { ... })
return { invoiceId, changeQuantity }
});
return invoiceId;
} catch (error: unknown) {
...
}
}, |
Beta Was this translation helpful? Give feedback.
-
Also consider to add transactions support for Accounts methods like createUser, sendEnrollmentEmail, sendVerificationEmail, etc. |
Beta Was this translation helpful? Give feedback.
-
I just want to point out one thing: handling of transaction failures (either transient or "actual" errors) is an important part of the business logic (you not always want to retry and sometimes you know it's safe to retry until success). "Hiding" it in the That's why I'd rather have the access to the underlying API with an explicit creation of the Also, since #11605 is already in progress, that may be much easier to expose this functionality. The only problem is to make sure it'll play well with the existing code, like server-generated IDs and schema validation (collection packages in general). |
Beta Was this translation helpful? Give feedback.
-
Maybe this discussion needs to be expanded into modernizing Meteor <-> MongoDB driver integration. I know there could be some breaking changes once Fibers are dropped. Maybe this can all make for a proper Meteor 3.0 release |
Beta Was this translation helpful? Give feedback.
-
I wrote this package for our app and it is working as expected for more than a year now. I also mentioned this in the thread you linked. It's basically the same as you proposed in your first example with Example:
|
Beta Was this translation helpful? Give feedback.
-
I might be misunderstanding something here, but the question I have is why not make use of the official node mongo driver (rawCollection) to handle a case like this? The fact that Meteor duplicates some of the official driver's API provides some benefits, but also comes at a cost. The benefits being that it works with minimongo, so enables optimistic updates, and operations are synchronous via Fibers, like most Meteor code. But the cost is rather heavy. Meteor needs to play catch-up with the offical node mongo driver and it will never be as feature complete as the official driver. Mongo transactions have been available for quite some time already for Meteor users using rawCollection. Yes, it requires the use of async code. But it is already clear that Meteor will need to get rid of Fibers soon. So it seems to me that it does not make sense to add any new Fibers based code anymore. And if async will be required anyway, using rawCollection for transactions seems like an easy step. As a more general note, I'd like to see Meteor promote the use of rawCollection a bit more, for example in the docs. Relying on the offical driver should be a very stable and tested way to interact with the db in Meteor, as Meteor apps are just node app at the end of the day. I don't think it should be regarded as using some obscure internal API that might break at any time. |
Beta Was this translation helpful? Give feedback.
-
Are there any updates on this feature request or more clarity in terms of fiber and MongoDb? |
Beta Was this translation helpful? Give feedback.
-
I just published a new package jam:mongo-transactions that was inspired by this discussion and builds on some of the ideas shared here. Here are some of the benefits:
Here's a quick example. As said above, you can surf the async vibe: import { Mongo } from 'meteor/mongo';
async function purchase(purchaseData) {
try {
const { invoiceId } = await Mongo.withTransaction(async () => {
const invoiceId = await Invoices.insertAsync(purchaseData);
const changeQuantity = await Items.updateAsync(purchaseData.itemId, { $set: {...} });
return { invoiceId, changeQuantity } // you can return whatever you'd like
});
return invoiceId;
} catch (error) {
// something went wrong with the transaction and it could not be automatically retried
// handle the error as you see fit
}
} If you end up taking it for a spin or have ideas on how to make it better, let me know! |
Beta Was this translation helpful? Give feedback.
-
Hey everyone,
It's still hard for me to believe that Meteor doesn't support MongoDB transactions. It was a really big feature when launched, and can potentially broaden the appeal of Meteor.
Looking from their API, it's a pretty simple set of steps to use:
Good reference with examples of how to use it: https://forums.meteor.com/t/solved-transactions-with-mongodb-meteor-methods/48677
For a Meteor implementation, we need to have the Fibers support working and maybe add a bit of sugar to it? At minimum, we shouldn't have to rely on internal APIs to have it working.
A few ideas to start the conversation...
I'm personally a fan of the example1, as anyone can pick up its use just seeing from a code sample, as well as easily migrate their existing code to support it.
I also have a specific use case with my jobs queue package, Steve Jobs, where I think this can really shine. The job state is stored in MongoDB, and the idea is, to perform all the DB operations that the job requires, and update the job state document, in one shot. For example:
Beta Was this translation helpful? Give feedback.
All reactions