I guess this still has the problem where another thread attempts to concurrently update the document in question. Consider the following sequence, thread 1 uses Fawn, thread 2 uses anything else:
In this case, we’ve lost the change made by T2. Transactions generally protect against this by locking the document (or row) in question until T1 has completed a rollback or a commit.
You’re right. It’s also mentioned in the MongoDB docs:
Because only single-document operations are atomic with MongoDB, two-phase commits can only offer transaction-like semantics. It is possible for applications to return intermediate data at intermediate points during the two-phase commit or rollback.
So it really depends on the use case. Most of the time in an application, you only have one update point per collection. If the app has multiple update points for a single collection, using two phase commits does become sketchy.
I’ve seen this happen in a variety of ways, most notably an error in a client leads to them sending the same request multiple times in quick succession, or the client has retry logic, or a user hits a button twice…