|PREV PACKAGE NEXT PACKAGE||FRAMES NO FRAMES|
|AccessSecurityIF||We may want to implement security at a field access level.|
|ObjectChangeRequest||The interface to objects that will keep track of details of a change to a transactional object.|
|ObjectEditingView||The interface to the object that will keep track of ObjectChanges.|
|TransactionalObjectIF||In order to be a transactional object it is necessary for this interface to be implemented.|
|ExampleObject||An example of a persistent business object that extends from TransactionalObjectAdapter.|
|ExpandingObjectModifiedArrayCache||Maintain a collection of ObjectModified objects.|
|ExpandingObjectModifiedCache||Maintain a collection of ObjectModified objects.|
|NoFieldObjectEditor||Tracks changes to a TransactionalObjectIF.|
|NoFieldObjectModified||The details of a change to a particular object.|
|ObjectEditor||Tracks changes to a TransactionalObjectIF.|
|ObjectModified||The details of a change to a particular object.|
|Session||A utility class to allow multiple threads share a single transaction context.|
|SessionManager||Used to manage multiple threads.|
|SupportedCollections||This is to allow the transactional support to work well with collections.|
|ThreadContext||This is used for performance optimization.|
|TransactionalObjectAdapter||A sample implementation of a TransactionalObject.|
|TransactionLog||A key piece of a the TransactionalSupport is the transaction log.|
|TransactionLog.Test||Unit tests for the tranasaction log.|
|TransactionManager.MyLockManager||A very efficient lock manager that takes advantage of the following assumptions.|
|WrapClassLoader||This is used for performance optimization.|
|UpdateException||This exception may be thrown when trying to commit changes to a transactional object.|
Provide the core functionality the allows us to 'commit' and 'rollback' changes to TransactionalObjects. The com.objectwave.transactionalSupport.ObjectEditor, com.objectwave.transactionalSupport.TransactionLog, and the com.objectwave.transactionalSupport.ObjectChangeRequest work together to provide commit and rollback functionallity to any object that implements the com.objectwave.transactionalSupport.TransactionalObject interface.
Lets start with the TransactionalObject interface.
void setObjectEditor(ObjectEditor edit);
Every TransactionalObject relates to an ObjectEditor. It is this relation that enables the transactional support. When a change is made, via one of the mutator methods (set methods), the actual set call is made to the ObjectEditor. The ObjectEditor will keep track of all of the changes made to the TransactionalObject.
void update(boolean get, Object  data, Field  fields);
This method provides a 'back door' to updating the values of a TransactionalObject. It is with this method
that we actually modify the TransactionalObject. Since any call to the accessor and mutator methods actually update
the ObjectEditor. Since we need to update variables that may be 'private' in scope this method MUST be implemented
on every TransactionalObject.
This will tell you if the ObjectEditor knows of any changes to the TransactionalObject. When we 'commit'
the changes, the TransactionalObject will no longer be dirty.
void setAsTransient(boolean value);
A Transient object is one that doesn't use the ObjectEditor. Any calls to the mutator method will directly update the TransactionalObject. This effectively removes our transactional capability of our TransactionalObject. There are some instances where we may wish to disable the commit, rollback functionality of an Object, and these methods enable us to do just that.
The TransactionLog is the key Object to manager your transactions. The key methods:
public static TransactionLog getCurrentInstance()
Return the current instance. Since we may have multiple or nested transactions, this the method that should be used to get the current instance. The current instance will in part be defined by the current context. When we create a transaction, we provide a context. Whenever a setContext(Object obj) method is called, our current instance will be changed based upon the context parameter. Frequently, transactions are based upon screen navigation, so frequently the context will be the GUI object.
To begin a transaction, use this method. This will take care of nesting issues. The parameter 'context'
is useful if you are going to have multiple transactions executing at the same time. You can associate a context
with a given transaction to enable switching between two transactions. If a transaction is already underway at
the time this command is issued, the new transaction is a subtransaction to the existing transaction. When we 'commit'
the new transaction, all of our changes are migrated to the existing (or parent) transaction. If, for some reason,
you exlicitly want a transaction to be a root transaction, you can use the startRootTransaction(TransactionLog
log, Object context) method.
public static void startTransaction(TransactionLog log, Object context)
public void commit() throws UpdateExceptionWhen a transaction is complete, and you wish to make all of the changes permanent, getCurrentInstance()
and commit() the changes.
public void rollback()
Similar to commit, however, this method just drops any changes made to the TransactionalObject.
You are now armed with enough knowledge to begin building transactional applications. Lets walk through some
high level event scenario diagrams to follow the flow of the application.
---startTransaction(aTransactionLog , null) ---> TransactionLog
|--For each ObjectEditor-->
There is one more step of complexity to this scenario. In the actual code, we also support multiple transactions
updating the same TransactionalObject. So the ObjectEditor not only keeps track of aField and aValue for a given
change, but the also the current TranasctionLog when the change occurred. When a TransactionLog asks the ObjectEditor
to commit(), the ObjectEditor commits only those changes found to occur in that particular transaction log.
An IMPORTANT NOTE: To make transactions work, all object state modifications MUST be done with attribute accessors.
|PREV PACKAGE NEXT PACKAGE||FRAMES NO FRAMES|