JackAdams / meteor-transactions

App level transactions for Meteor + Mongo
http://transactions.taonova.com/
MIT License
113 stars 16 forks source link

every commit is rolled back after 5 seconds. #59

Open gferreri opened 8 years ago

gferreri commented 8 years ago

Hi, just familiariizing myself with this package, but I'm having some problems getting any transactions to successfully commit. I want to edit a set of documents in one transaction, so I created a transaction with the start function and I'm ending with a call to tx.commit. However, after 5 seconds I see an error that the transaction timed out and is rolled back. What am I doing wrong?

In the snippet below, I'm calling update several times to update many documents, then calling commit at the end.

    tx.start('shiftPlanIndex')
    if (oldIndex < newIndex) {
      let tasksToShift = Tasks.find({
        $and: [
          {planId: { $eq: task.planId }},
          {planIndex: { $lte: newIndex }}
        ]
      }).fetch()
      tasksToShift.forEach(t => {
        Tasks.update({_id: t._id}, {$set: { planIndex: t.planIndex - 1 }}, { tx: true })
      })
    }
    Tasks.update(taskId, {$set: { planIndex: newIndex }}, { tx: true })
    tx.commit()

The output looks like this:

Started "shiftPlanIndex" with transaction_id: WZF3DDWQpdEjdg4FT I20160627-13:23:14.429(-4)? Pushed update command to stack: WZF3DDWQpdEjdg4FT I20160627-13:23:14.429(-4)? Pushed update command to stack: WZF3DDWQpdEjdg4FT I20160627-13:23:14.429(-4)? Pushed update command to stack: WZF3DDWQpdEjdg4FT I20160627-13:23:14.430(-4)? Pushed update command to stack: WZF3DDWQpdEjdg4FT I20160627-13:23:14.430(-4)? Beginning commit with transaction_id: WZF3DDWQpdEjdg4FT I20160627-13:23:19.432(-4)? Transaction (WZF3DDWQpdEjdg4FT) was cancelled after being inactive for 5 seconds. I20160627-13:23:19.439(-4)? Rollback reset transaction manager to clean state

JackAdams commented 8 years ago

Strange, that looks fine to me. It just looks like the tx.commit() function isn't being called. Maybe an error is getting swallowed silently (which would be an issue with the package), breaking the event loop with the tx.commit() in it, while the Meteor.setTimeout call that checks the transaction is committed in reasonable time is still running (as it was initiated before the error). Normally, in this situation, I'd expect to see an error reported in the console though.

I'm not overly familiar with ES2015 syntax, so I would have written:

    tx.start('shiftPlanIndex');
    if (oldIndex < newIndex) {
      var tasksToShift = Tasks.find({
        $and: [
          {planId: { $eq: task.planId }},
          {planIndex: { $lte: newIndex }}
        ]
      });
      tasksToShift.forEach(function (t) {
        Tasks.update({_id: t._id}, {$set: { planIndex: t.planIndex - 1 }}, { tx: true });
      });
    }
    Tasks.update({_id: taskId}, {$set: { planIndex: newIndex }}, { tx: true });
    tx.commit();

but I think it amounts to the same thing.

Maybe try the above code block above and see if there's any difference in the result.

JackAdams commented 7 years ago

0.8.2 contains some changes that might help with this (some improvements to error handling).