FileDocCategorySizeDatePackage
OracleXAResource.javaAPI DocGlassfish v2 API9385Fri May 04 22:35:58 BST 2007com.sun.enterprise.transaction

OracleXAResource

public class OracleXAResource extends XAResourceWrapper
This implements workaround for Oracle XAResource. Oracle's 8.1.7 XAResource implementation doesn't work fine while recovery. This class fires sql statements to achieve same.
author
Bala Dutt
version
1.0

Fields Summary
private static final com.sun.enterprise.util.i18n.StringManager
sm
private static final Logger
_logger
private static final char[]
HEX_DIGITS
Constructors Summary
Methods Summary
public voidcommit(javax.transaction.xa.Xid xid, boolean flag)

        doRecovery(xid, true);
    
private voiddoRecovery(javax.transaction.xa.Xid xid, boolean isCommit)
Does actual recovery depending on boolean argument - true for commmit.

param
xid a Xid value
param
isCommit a boolean value
exception
XAException if an error occurs


        try {
            if (isCommit)
                m_xacon.getXAResource().commit(xid,true);
            else
                m_xacon.getXAResource().rollback(xid);
        } catch (XAException ex) {
            _logger.log(Level.FINEST," An XAException occurred while calling XAResource method " , ex);
        } catch (Exception ex) {
            _logger.log(Level.FINEST," An Exception occurred while calling XAResource method " , ex);
        }

        Statement stmt = null;
        ResultSet resultset = null;
        Connection con = null;
        try{
            con=(Connection)m_xacon.getConnection(subject,null);
            if(null == con)
                throw new XAException(sm.getString("transaction.oracle_xa_wrapper_connection_failed"));
                // throw new XAException("Oracle XA Resource wrapper : connection could not be got");
            stmt = con.createStatement();
            resultset = stmt.executeQuery(
                "select pending.local_tran_id from SYS.PENDING_TRANS$ pending, SYS.DBA_2PC_NEIGHBORS dba where pending.global_foreign_id = '"
                + toHexString(xid.getGlobalTransactionId()) +
                "' and pending.local_tran_id = dba.local_tran_id and dba.branch = '"
                + toHexString(xid.getBranchQualifier()) +
                "' and pending.state = 'prepared'");
            if(resultset.next()){
                String s = resultset.getString(1);
                resultset.close();
                resultset = null;
                stmt.executeUpdate((isCommit ? "commit force '" : "rollback force '") + s + "'");
                stmt.close();
                stmt=null;
            }
        }
        catch(SQLException sqlexception){
            //Trace.info("Failed to recover " + xid+" "+ sqlexception);
            _logger.log(Level.FINE," An SQLException during recovery " , sqlexception);
            throw new XAException(sm.getString("transaction.oracle_sqlexception_occurred",sqlexception));
            // throw new XAException("oracle XA Resource wrapper : "+sqlexception);
        }
        catch(Exception e){
            //Trace.info("Exception while RecoveryTestRI recover "+e);
            _logger.log(Level.FINE," An Exception during recovery " , e);
            throw new XAException(sm.getString("transaction.oracle_unknownexception_occurred",e));
            // throw new XAException("oracle XA Resource wrapper : "+e);
        }
        finally{
            if(null != resultset)
                try{
                    resultset.close();
                }
                catch(SQLException sqlexception1) { }
            if(null != stmt)
                try{
                    stmt.close();
                }
                catch(SQLException sqlexception2) { }
        }
    
public javax.transaction.xa.Xid[]recover(int flag)
Recovers list of xids in transaction table. Recover on oracle ignores flags sent to it, this method takes care of flags in addition to calling recoverList for xid list.

param
flag an int value
return
a Xid[] value
exception
XAException if an error occurs


	
                                                 
          
        if(flag==XAResource.TMNOFLAGS)
            return null;
	return recoverList(flag);
    
private javax.transaction.xa.Xid[]recoverList(int flag)
Fires a select statement so that transaction xids are updated and retrieve the xid list. Oracle doesn't update the xid's for sometime. After this update, recover of real oracle xa resource is is used get xid list.

return
a Xid[] value
exception
XAException if an error occurs

        Statement stmt = null;
        ResultSet resultset = null;
        Connection con = null;
        try{
            con=(Connection)m_xacon.getConnection(subject,null);
            if(null == con)
                // throw new XAException("Oracle XA Resource wrapper : connection could not be got");
                throw new XAException(sm.getString("transaction.oracle_xa_wrapper_connection_failed"));
            stmt = con.createStatement();
            resultset = stmt.executeQuery(
                "select pending.local_tran_id from SYS.PENDING_TRANS$ pending, SYS.DBA_2PC_NEIGHBORS");
            resultset.close();
            resultset = null;
            stmt.close();
            stmt=null;
            return m_xacon.getXAResource().recover(flag);
        }
        catch(SQLException sqlexception){
            //Trace.info("Failed to recover xid list");
            // throw new XAException("oracle XA Resource wrapper : "+sqlexception);
            throw new XAException(sm.getString("transaction.oracle_sqlexception_occurred",sqlexception));
        }
        catch(Exception e){
            throw new XAException(sm.getString("transaction.oracle_unknownexception_occurred",e));
            // throw new XAException("oracle XA Resource wrapper : "+e);
        }
        finally{
            if(null != resultset)
                try{
                    resultset.close();
                }
                catch(SQLException sqlexception1) { }
            if(null != stmt)
                try{
                    stmt.close();
                }
                catch(SQLException sqlexception2) { }
        }
    
public voidrollback(javax.transaction.xa.Xid xid)

        doRecovery(xid, false);
    
private static java.lang.StringtoHexString(byte[] abyte0)
Converts Xids into string that can be used in sql statements for oracle.

param
abyte0[] a byte value
return
a String value

                           
       
        StringBuffer stringbuffer = new StringBuffer();
        if(null != abyte0 && 0 < abyte0.length) {
            for(int i = 0; i < abyte0.length; i++) {
                stringbuffer.append(HEX_DIGITS[(abyte0[i] & 0xf0) >> 4]);
                stringbuffer.append(HEX_DIGITS[abyte0[i] & 0xf]);
            }
            return stringbuffer.toString();
         } else {
            return "";
         }