There are essentially two kinds of transactions supported within the Cut The Crap software.

Native Storage Transactions

These are transactions that ensure that no irreversible update is made to any persistent store before the transactions is complete.

The Object Manager - and for convenience every GPO instance provide methods startNativeTransaction, commitNativeTransaction and rollbackNativeTransaction to support this.

At this level, the concept of "nested" transactions is simply provided as a "bracketing" of the real transaction. Or to say it more plainly, that an internal count is incremented and decremented with the calls, and when it is decremented to 0 the final commit is made.

For many situations, native transactions are all that are needed. They are effective and very efficient. Any processing intensive task can safely and efficiently be carried out within a native transaction - there is no sizing issue when working with native transactions, as updates are made incrementally to the backing store.

Transaction Objects - Shadow Object Managers

If your application is likely to use multiple threads, and that more than one thread at a time will be likely to make update requests. Then you should use Transaction objects.

A Transaction object is correctly understood to be a shadow object manager.

Transactions are created by an IObjectManager object, and a Transaction object itself implements IObjectManager.

Consider the following python :

>>> from cutthecrap.gpo.client import OMClient;
>>> from cutthecrap.gpo import *;
>>>
>>> om = OMClient("", "/ctc/db/ex1.gpo");
>>> g1 = GPOMap(om);
>>> g1.set("name", "first");
>>> om.remember("test", g1);

Now we'll create a Transaction..

>>> t = om.createTransaction();
>>> g2 = t.recall("test");
>>> g2.get("name");
'first'
>>> g2.set("name", "second");
>>> g2.get("name");
'second'
>>> g1.get("name");
'first'
>>> t.commit();
>>> g1.get("name");
'second'

Take a look at the sequence above and make sure you understand what is going on.

createShadow

Suppose you have navigated around the GPO model and have now found an object that you want to update within a Transaction object. You need to somehow bring the object into the shadow transaction context. Here is how you do it :

>>> t = om.createTransaction();
>>> g1s = t.createShadow(g1);
>>> g1s.set("name", "third");
>>> t.commit();
>>> g1.get("name");
'third'