Hi,

A bit more details below. I haven't had time to look in detail at the existing implementation.

Some points on the inner workings:

*** Collections ***

- Typically working with a shared resource is done by creating a map with the resource values, and then instantiating an XAMap, passing the shared map to it's constructor.

This creates a Map-specific specialization of the AbstractResourceManager, that is capable of creating new transaction scopes (individual internal transaction representations) as well as provide an XAResource implementation.

- The XAMap instance implements the Map interface and can now be used directly from surrounding code.

Calls to these interface methods are delegated to the transaction-local Map representation which is which is an instance of the XAMapResource implementation that also implements the Map interface (XAMapResource). There is one of these for each active transaction.

- The XAResource implementation creates the data structures required to hold transaction-scope specific data, when asked to do so by the TransactionManager.

For the XAMapResource implementation the ProxyXAScope is used. Invocations of Map-interface methods on the XAMapResource use this scope instance for keeping track of changes.

- The scope implementation provides two important features: a transaction log, and 'shadowing'. Initially it takes a full copy (clone) of the shared resource - this could be improved substantially.

- Whenever a reading invocation occurs
1) The invocation is delegated to the scope-specific proxy, that can also be considered a Map which reads from the shadow. 2) If a complex collection-backed instance is returned (such as the key set or a ListIterator) it is wrapped for similar functionality. Returned instances (elements) are also wrapped if they implement one of the included XA-collection interfaces, such that nested collections participate in the same transaction.

- Whenever a mutating invocation occurs
  1) The resource is locked for mutation by others
2) The invocation is delegated to the scope-specific proxy, that can also be considered a Map, which puts the invocation in the log and reads from the shadow.

- Obvious improvements to the above:
  - Better locking granularity or MVCC implementation
  - Less wasteful shadow implementation. Copy-on-read.

*** Object model ***

- The XAObject implementation wraps all returned instances in a dynamic proxy which intercepts all invocations, and similarly puts them in the associated scope's transaction log and applies the method invication to a cloned instance.

This implementation uses the IdentityXAScope instead and performs copy-on-read-as-well-as-write. It also locks on "instance granularity".

- Obvious improvements to the above:
  - MVCC implementation
  - Support direct field-modification (class instrumentation required)
  - Disable cloning for more known immutable types
- Declarative read-only optimization - or perhaps even automatic detection of whether an invocation is read or write (could be done with field interceptors - again: requires class instrumentation).


I am unsure how resource enlistment to the TransactionManager should work, as mentioned in a comment in jira. For now the collections enlist themselves, when created. What's the best way to go about this? I guess there must be some j2ee-mandated way of enlisting a resource?


Let me know what you think.

-dennis
---------------------------------------------------------------------------
The information in this email is confidential and may be legally protected.


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to