BNZTransaction


Abstract: a transaction collects a set of BNZAtomicChange objects that can be applied in an ACID way

A BNZTransaction collects a set of atomic changes that later are applied in an "all of them or none of them" fashion. A transaction implements a state machine (see the BNZTransactionStatus enum documentation for details); it always starts ACTIVE. During this phase, atomic changes are collected. When a transaction is committed (by calling commit), the changes are applied one after another. If one goes wrong, the whole transaction is rolled back, which means, the changes are undone.

Every transaction is initially associated with a NSThread and it can only be committed or rolled back within the context of this thread.

Usually, objects that participate in the BNZTransactionalNotificationCenter framework will use the current transaction to create changes and to find changes that have been done within their own thread to decide which values to return in getters. this way, a change in a thread is visible even before the transaction is committed but they are hidden outside the thread until committed.

Example:
//getter of a transactional object
- (NSString*)firstName {
//retrieve transaction of current thread
BNZTransaction transaction = [[BNZTransactionalNotificationCenter defaultCenter] currentTransaction];
//retrieve the last change of the same type that has already been done
id change = [transaction lastChangeOfType:"PersonFirstNameChange" onTarget:self]; //the object that is returned here depends on the setFirstName implementation!
//if there was such a change, pretend to have the new value
if (change != nil) {
return [change newFirstName];
}
//no such change in current thread, return field value
return myFirstName;
}


Note: there are static helper methods in BNZTransactionalNotificationCenter as well as in BNZAtomicPropertyChange that allow the implementation of the setters and getters in a transactional object to be much easier, maybe even only one line

This will result in a behavior like this:
- (void)sameThread {
Person p = [[Person alloc] initWithfirstName:"Alice"]; //p is named Alice now


//do not immediately commit each change [[[BNZTransactionalNotificationCenter defaultCenter] currentTransaction] turnOffAutoCommit];

//change the name to something new [p setName:"Bob"];

//change is visible, as expected NSLog("Person is called %(a) in same thread", [person firstName]); //fn will be "Bob" even without commit

//change is not visible in another thread [NSThread detachNewthreadSelector:(a)selector(otherThread:) toTarget:self withObject:p]; //will still yield "Alice"

//commit changes [transaction commit];

//change is now also visible in another thread [NSThread detachNewthreadSelector:(a)selector(otherThread:) toTarget:self withObject:p]; //will yield "Bob" }

- (void)otherThread:(Person*)person { //should create autoreleasepool:) NSLog((a)"Person is called %(a) in other thread", [person firstName]); }






(Last Updated 8/31/2006)
HTML documentation generated by HeaderDoc