Hackers, I've been looking at what is involved into making nested transactions possible. So far I've identified the following things. Please comment. Additions are welcome.
Resource Management ------------------- We will create and select a new memory context for each subtransaction. This context will be deleted on transaction abort/commit. Some At{Abort,Commit,EOX}act_*() actions will be executed at the end of the subtransaction (indexes, GUC, Locks. Memory), while others will be delayed (on_commit_actions, smgrDoPendingDeletes) till toplevel transaction commit. Most of there routines will have to be revised so they do The Right Thing. Locking ------- The ProcReleaseLocks()/LockReleaseAll() interaction will have to be modified to not just "release all locks" on abort. It currently does the right thing on commit, but the check for abort will have to be more fine-grained. Transaction State ----------------- We will add a field to TransactionStateData with the xid of the parent transaction. If it's set to InvalidTransactionId, then the transaction is a parent transaction [maybe we only need a boolean, since we can get the parent transaction from the subtransaction tree anyway -- another idea would be using a integer to denote nesting level, but how is that useful?] Whenever a transaction aborts, the backend is put into TRANS_ABORT state only if it is a toplevel transaction. If it is not, the backend is returned to TRANS_INPROGRESS, the TransactionId goes back to the parent (sub)transaction Id, and the pg_clog records the transaction as aborted. The subtransaction tree may delete the corresponding branch. Commit/abort protocol in pg_clog -------------------------------- For a toplevel transaction, commit is: - write 01 as state of xid - write 01 as state of each non-aborted subtransaction For a toplevel transaction, abort is: - write 10 as state of xid - write 10 as state of each non-aborted subtransaction For a non-toplevel transaction, commit does nothing. For a non-toplevel transaction, abort is: - write 10 as state of xid - write 10 as state of each non-aborted subtransaction. Tuple Visibility ---------------- We keep the xmix/xmax protocol for tuple visibility. To determine the state of a transaction, we determine if it's a toplevel transaction. If it is, report the pg_clog value directly. For a non-toplevel transaction, the protocol is as follows: - if the state is 01, it is committed - if the state is 10, it is aborted - if the state is 00: - if it's toplevel, it's in progress - if parent is 01, start again - if parent is 10, it is aborted - if parent is 00, check parent Subtransaction tree ------------------- I don't know how this will be, but the subsystem will have to answer the following questions: - Xid of my parent transaction - List of Xids of non-aborted child transactions -- Alvaro Herrera (<alvherre[a]dcc.uchile.cl>) "Hay que recordar que la existencia en el cosmos, y particularmente la elaboración de civilizaciones dentre de él no son, por desgracia, nada idílicas" (Ijon Tichy) ---------------------------(end of broadcast)--------------------------- TIP 4: Don't 'kill -9' the postmaster