org.jboss.jbossts.txbridge.inbound.BridgeVolatileParticipant Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright 2009, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*
* (C) 2009 @author JBoss Inc
*/
package org.jboss.jbossts.txbridge.inbound;
import com.arjuna.ats.jta.utils.XAHelper;
import com.arjuna.wst.*;
import com.arjuna.ats.internal.jta.resources.spi.XATerminatorExtensions;
import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
import com.arjuna.ats.jta.utils.JTAHelper;
import org.jboss.jbossts.txbridge.utils.txbridgeLogger;
import javax.transaction.xa.Xid;
import javax.transaction.Status;
/**
* Provides method call mapping between WS-AT Volatile Participant interface
* and an underlying JTA subtransaction coordinator.
*
* @author [email protected], 2009-06-01
*/
public class BridgeVolatileParticipant implements Volatile2PCParticipant
{
// no standard interface for driving Synchronization phases separately
// in JCA, so we have to use proprietary API.
private final XATerminatorExtensions xaTerminatorExtensions;
private final String externalTxId;
private final Xid xid;
/**
* Create a new WS-AT Volatile Participant which wraps the subordinate XA tx terminator.
*
* @param externalTxId the WS-AT Tx identifier
* @param xid the Xid to use when driving the subordinate XA transaction.
*/
BridgeVolatileParticipant(String externalTxId, Xid xid)
{
txbridgeLogger.logger.trace("BridgeVolatileParticipant.(TxId="+externalTxId+", Xid="+xid+")");
this.xid = xid;
this.externalTxId = externalTxId;
this.xaTerminatorExtensions = (XATerminatorExtensions)SubordinationManager.getXATerminator();
}
/**
* Perform beforeCompletion activities such as flushing cached state to stable store.
*
* @return an indication of whether it can prepare or not.
* @see com.arjuna.wst.Vote
*/
public Vote prepare() throws WrongStateException, SystemException
{
txbridgeLogger.logger.trace("BridgeVolatileParticipant.prepare(Xid="+xid+")");
// Usually a VolatileParticipant would return Aborted to stop the tx in error cases. However, that
// would mean rollback() would not be called on the instance returning Aborted, which would make it
// hard to invoke afterCompletion on the subordinate. So we cheat a bit by using setRollbackOnly instead.
// A slightly more efficient but less clear impl would be to have the same object implement both the Volatile
// and Durable Participants and keep count of the number of prepare/rollback invocations to know
// if being invoked as Volatile or Durable.
InboundBridge inboundBridge = InboundBridgeManager.getInboundBridge(externalTxId);
try
{
// TODO: check for rollbackOnly before bothering to invoke?
// beforeCompletion should run in tx context.
inboundBridge.start();
if(!xaTerminatorExtensions.beforeCompletion(xid))
{
txbridgeLogger.i18NLogger.warn_ibvp_preparefailed(XAHelper.xidToString(xid), null);
inboundBridge.setRollbackOnly();
}
return new Prepared();
}
catch(Exception e)
{
txbridgeLogger.i18NLogger.warn_ibvp_preparefailed(XAHelper.xidToString(xid), e);
try
{
inboundBridge.setRollbackOnly();
}
catch(Exception e2)
{
txbridgeLogger.i18NLogger.warn_ibvp_setrollbackfailed(e2);
}
return new Prepared();
}
finally
{
try
{
inboundBridge.stop();
}
catch(Exception e)
{
txbridgeLogger.i18NLogger.warn_ibvp_stopfailed(XAHelper.xidToString(xid), e);
}
}
}
/**
* Perform afterCompletion cleanup activities such as releasing resources.
*
* Caution: may not be invoked in crash recovery situations.
*/
public void commit() throws WrongStateException, SystemException
{
txbridgeLogger.logger.trace("BridgeVolatileParticipant.commit(Xid="+xid+")");
afterCompletion(Status.STATUS_COMMITTED);
}
/**
* Perform afterCompletion cleanup activities such as releasing resources.
*
* Caution: may not be invoked in crash recovery situations.
*/
public void rollback() throws WrongStateException, SystemException
{
txbridgeLogger.logger.trace("BridgeVolatileParticipant.rollback(Xid="+xid+")");
afterCompletion(Status.STATUS_ROLLEDBACK);
}
/**
* Invoke afterCompletion on the subordinate JTA tx.
*
* @param status a javax.transaction.Status value, normally STATUS_COMMITTED or STATUS_ROLLEDBACK
*/
private void afterCompletion(int status)
{
txbridgeLogger.logger.trace("BridgeVolatileParticipant.afterCompletion(Xid="+xid+", status="+status+"/"+JTAHelper.stringForm(status)+")");
// this is a null-op, the afterCompletion is done implicitly at the XAResource commit/rollback stage.
}
/**
* Deprecated, should never be called.
*/
public void unknown() throws SystemException
{
txbridgeLogger.logger.trace("BridgeVolatileParticipant.unknown(Xid="+xid+"): NOT IMPLEMENTED");
}
/**
* VolatileParticipants don't support recovery, so this should never be called.
*/
public void error() throws SystemException
{
txbridgeLogger.logger.trace("BridgeVolatileParticipant.unknown(Xid="+xid+"): NOT IMPLEMENTED");
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy