Question about two phase commit

So I was reading about this two phase commit:
http://docs.couchbase.com/couchbase-devguide-2.5/#performing-two-phase-commits

AFAIK, Couchbase operation is atomic.
Article explains when performing two phase commit I should create a Trans:1 document, which contains the state of the Transaction progress.

  1. First is start at Init state.

  2. When Transaction start begin process, I should switch Trans:1’s state to pend.
    By switching to pend state, we can prevent other process pickup the same transaction.

  3. Then update the target document’s content (in example is dipti and karen) to include a trans the same time.
    *If anything fail during the update on either document, we can do a rollback, by checking the trans:1 document’s state is equals to pend *

So here is my questions:

a) Since Couchbase operation is atomic, if there is multiple processes try to come pickup the transaction trans:1, there is chance say process A got trans:1’s state = init, before process A update trans:1’s state = pend, process B may also got the same result trans:1’s state = init and try to perform the update.

b) Same reason, when a process updated trans::1 state to pend, update dipti and karen. Because operation is atomic, they cannot really update the same time, only can be update one after another.
Then how can we prevent other process not getting/updating the value of dipti and karen? Because their values is not completely updated.

c) Couchbase is not versioning like Couchdb, how do we do rollback actually?

d) What is the point of keeping trans:1 and set to state:done? Why not just delete the whole document when we know is done?

e) Last question, actually how should I make the transaction document being pickup? I mean like should I run a service that will constantly checking all the Transition document in Linux or something? Running everytime when machine got rebooted?

(The example and codes there using cas() method, I have no idea what is the equivalent in PHP SDK, I imagine is means get()? )

Currently my approach is:
When trans:1 is state:init the process will getAndLock all necessary documents (dipti and karen) and create copy of each of the documents (trans:1::dipti etc)
When trans:1 is state:pend the process will update each document with state:Processed, so I know which documents got updated and need to rollback (from the copy of documents) if any failure.
And rollback will remove all copy documents and as well as the trans:1.

But it still doesn’t prevent other process able to get dipti and karen while both is being updating. (i.e. Get total of amount of all people).

1 Like

Yeah I do have the same question, actually I want to perform updation on three documents transactionally, but I was not able to get a clear insight. Any help is appreciated.

I have the same issue, did you find solution?

Nesting all 3 documents in a single document is one approach