commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dennis Thrys√łe <>
Date Tue, 12 Jun 2007 10:10:01 GMT

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 

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.

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

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message