-
Notifications
You must be signed in to change notification settings - Fork 16
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
Bug: The rollback function attempts to _changeItemState on items that do not exist in the database #98
Comments
Thank you for the comprehensive analysis of the problem and my apologies for the weakness in the package. This certainly needs addressing. If possible, can I take a look at the database record (in the |
Thanks so much for your quick response, and for this very useful package! Yes, we are using the default If it's relevant, we are using Simple Schema, and I can send you the schemas for all of our collections if you would like. We made sure each of them includes the following (see #2):
I'd be happy to share the document in |
This is just a for-the-record, and has no impact on the issue at hand, but at some stage I changed the schema for
That's all right about sending the document in Not sure when I'll be able to roll out a fix - I'm pretty slammed at the moment - but it's now on the to-do list. |
Oh nice! So I don't have to manually extend my schemas with that, it sounds like. Let me know if you have a general idea of what should be done, and I can try to put together a pull request. |
Right. The package should automatically extend any schema for you. I'm going to try to reproduce the error with test and then go from there. I'd thought the whole Let me do some poking around and I'll give a call out if I could use some help. |
Thank you! Please let me know if I can help out at all. |
Two error messages:
The second is very puzzling, and I think it can be handled better. More importantly, my transaction failed and was incorrectly rolled back.
The cause of the second error message:
My own code threw an unrelated error after performing some inserts, updates, and deletes, but before
tx.commit
was called. Some of these inserts, updates, and deletes were called withinstant: true
, and some weren't. From looking attransactions-common.js
, I can see that theinstant
operations are recorded in the database as soon as they are called, whereas non-instant
operations are not recorded in the database untiltx.commit
is called. All operations, whetherinstant
or not, are recorded in memory on the server inself._items
. This means that there is some time, between performing an operation and callingtx.commit
, during which the server's record of performed operations might contain more items than the transaction document in the database. But in my case, and due to my own code error,tx.commit
was never called, so this difference in record-keeping persisted. It persisted beyond the 5-second inactivity timeout, which calledrollback
, and this became a problem.The
rollback
method usesself._items
as its record of operations that need to be reversed.rollback
attempted to loop over 6 items, 4 of which weren't recorded in the database because they weren't doneinstant
ly (remember the difference I just described). The following was called 6 times, once for each item stored inself._items
:_changeItemState
writes to the transaction document like so:Looking at the intended behavior, the first write to the transaction document will be to index 5 of the
items
array, because the rollbacks are done in reverse order. Next will be 4, then 3, and so on, down to 0. Sinceitems[5]
does not exist in the database, however, the array will have to be expanded from containing 2 items to containing 6 items, making index 5 available. Mongo seems to do this automatically by writingnull
to indexes 2, 3, and 4, and writing to index 5 correctly. So far, no error. But on the next iteration of the loop, it's time to write toitems[4]
. Do you see the problem? Right --items[4]
is nownull
, and you can't write a property such as.state
tonull
. Read the second error message again, and this time it should make sense!The solution:
The most obvious thing I should have done is not write buggy code. And yet it happened, triggering an incomplete rollback of the transaction, and a very cryptic error message. Can someone comment on the feasibility of somehow getting
self._items
to sync up with theitems
array on the transactions document in the database, even whencommit
doesn't get called? Perhaps this can be done at the beginning of therollback
function?The text was updated successfully, but these errors were encountered: