I did try to answer your question, and I don't think I made myself clear enough.
There is *no* contradiction. Here is why:
> My first question is that the manual is a contradiction.
> The manual is saying I should query pending state document and set those documents to pending state. what is that?
> if the state is pending, why should I set to pending again?
I think you're misreading the query part:
db.accounts.update(
{ name: t.source, pendingTransactions: { $ne: t._id } },
{ $inc: { balance: -t.value }, $push: { pendingTransactions: t._id } }
)
db.accounts.update(
{ name: t.destination, pendingTransactions: { $ne: t._id } },
{ $inc: { balance: t.value }, $push: { pendingTransactions: t._id } }
)
This says update the account if pendingTransactions NOT EQUALS
transaction id ($ne:
http://docs.mongodb.org/manual/reference/operator/query/ne/)
> My second question (rollback): the manual ask me to undo the transaction before you apply the transaction.
> This is another contradiction. why should you undo a transaction which never happens?
This is not a contradiction because of the query condition for the update:
db.accounts.update({name: t.source, pendingTransactions: t._id},
{$inc: {balance: t.value}, $pull: {pendingTransactions: t._id}})
db.accounts.update({name: t.destination, pendingTransactions: t._id},
{$inc: {balance: -t.value}, $pull: {pendingTransactions: t._id}})
Note that the query includes the account name *AND* pendingTransaction
id. If the transaction never happened, this update will find ZERO
documents to update.
If the transaction did happen, and needs to be rolled back, then the
first time you run this update, it will find the transaction id and it
will update and balance *and* pull the transaction id from the pending
array *ATOMICALLY* so that if you run the same update again, it will
not find a matching document so there is no risk of doing the rollback
more than once.
The reason I said you should just try it (follow along with the steps
in the manual cutting and pasting every operation) is that you can
then *see* what happens.
Another way of thinking about those update statements is like they are
saying to the DB to do this:
For applying transaction:
IF the transaction has not yet been applied, then { adjust balance and
add transaction id indicating that it happened }
Otherwise (if transaction already happened) do nothing.
For applying the rollback of the transaction:
IF the transaction was applied to this account, then { adjust the
balance and remove indication that transaction happened }
IF the transaction was not applied then do nothing.
Asya
> To view this discussion on the web visit
https://groups.google.com/d/msgid/mongodb-user/28366b51-81c3-4d5c-a4b8-7700b54accdf%40googlegroups.com.