users@jta-spec.java.net

[jta-spec users] Re: portable way to restore XAResources required

From: Paul Parkinson <paul.parkinson_at_oracle.com>
Date: Tue, 7 Aug 2012 12:32:06 -0400

Fyi, I've created http://java.net/jira/browse/JTA_SPEC-2 for this. I do not see this going into JTA 1.2.

Thanks,
Paul

On Jun 21, 2012, at 4:49 AM, Jonathan Halliday wrote:

>
> On 06/21/2012 08:47 AM, Christian Romberg wrote:
>> Hi Jonathan,
>>
>> I agree, that extending XAResource or the enlistResource call are far
>> superior to what I have suggested, however IMO it would also mean
>> more work for all existing implementation. (Btw. I'm curious to know,
>> how many implementations, which have really seen
>> production use, are there at all?)
>
> The JTA impl is really split betweem TM and RM.
>
> Current implementations of a transaction manger? one from IBM, two or three from Oracle (mostly by acquisition), one from JBoss and around four from smaller players.
>
> The number of XAResource implementations is larger though. Perhaps a hundred spread over JDBC drivers, JMS and JCA connector implementations?
>
> The cross product of those TMs and RMs is large enough to cause headaches for sure, but it should be possible to do recovery wiring in a backwards compatible way so the implementations can take place incrementally.
>
> Much as I'd like to get recovery wiring fixed I can't help thinking the solution would be more elegant if we wait for the Java SE changes that will facilitate extending interfaces by providing default method implementations. Without that we'll wind up back in TransactionSynchronizationRegistry territory, which is not a particularly pleasant prospect.
>
>>
>> I could imagine, that all ResourceManagers in a system could be required
>> to register similar to e.g. either the mechanism used
>> for JDBC drivers or for different JPA implementations, and they could
>> implement something like this
>>
>> interface Recovery {
>> XAResource getXAResource(byte[] recoveryInformation); //returns
>> null, if recoveryInformation is from a different implementation
>> }
>>
>> XAResource could be extended as follows:
>>
>> interface XAResource {
>> //...
>> byte[] getRecoveryInformation()
>> }
>>
>> The result of getRecoveryInformation() would be opaque and stored in the
>> transaction log file of the transaction manager.
>> Each Resource Manager would be responsible to include all information it
>> needs in there.
>>
>> Through the "resource manager registry" they could be probed later with
>> exactly this information and be required, to
>> determine, is it their information or that of a different resource manager.
>> If it's their information, they are required to return an XAResource
>> instance that can be used for recovery.
>> If they return null, the next registered resource manager is probed.
>
> I'm averse to anything that requires additional bytes to be forced to disk on each transaction. It's not necessary for obtaining the in-doubt list from an RM. For that you need only one XAResource for the entire RM, not one per tx.
>
> TransactionManager.registerForRecovery(XAResource xaResource)
>
> to be called y the container at datasource deployment time appears at first glance to be reasonable. Turns out it's not sufficient though. First up you also need to cope with deregistration so that datasources/connectors can be undeployed without a restart of the container. Then you need to cope with XAResources that get stale over time e.g. because the RM bounced and the TCP connection they are sitting on is now invalid. We could force RM implementers to mask that, but better to allow the TM to retrieve a fresh XAResource as needed
>
> TransactionManager.registerForRecovery(XARecovery recovery)
> TransactionManager.unregisterFromRecovery(XARecovery recovery)
>
> interface XARecovery {
> XAResource getXAResource(); // to be called by the TM's recovery system.
> }
>
> which then leaves you with thorny questions about how and when to release the XAResource so they don't leak. Still, you see where I'm going with this - it avoids any additional logging so the recovery overhead is not proportional to the transaction rate.
>
> Of course for cases where you want to automatically recognise and delete a TM log entry for a branch the RM has already committed, then you do need data that will associate a recovery XAResource with the log entry. That's where the JNDI name thing comes in, although it may also be possible to do clever things with Xid encoding in some cases. Right now we basically extend XAResource
>
> interface AnnotatedXAResource extends XAResource {
> byte[] getJNDIName()
> }
>
> clearly with interface extension methods we'd be able to put that new method direct on XAResource rather than needing a subclass, but we have to work with what we've got.
>
>
> Jonathan.
>
> --
> Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham (USA), Mark Hegarty (Ireland), Matt Parson
> (USA), Charlie Peters (USA)