All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.enterprise.transaction.jts.recovery.OracleXAResource Maven / Gradle / Ivy

The newest version!
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */
// Portions Copyright [2019] Payara Foundation and/or affiliates

//Source File Name:   OracleXAResource.java

package com.sun.enterprise.transaction.jts.recovery;

import com.sun.enterprise.transaction.api.XAResourceWrapper;
import com.sun.enterprise.util.i18n.StringManager;
import com.sun.logging.LogDomains;

import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * 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
 */
public class OracleXAResource extends XAResourceWrapper
{

    // Use superclass for Sting Manager
    private static final StringManager sm = StringManager.getManager(XAResourceWrapper.class);

    // Use JTA_LOGGER for backward compatibility, so use a class from
    // 'jta' bundle to load it.
    private static final Logger _logger = LogDomains.getLogger(
            com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.class,
            LogDomains.JTA_LOGGER);

    public XAResourceWrapper getInstance() {
        return new OracleXAResource();
    }

  /**
   * 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
   */
    public Xid[] recover(int flag) throws XAException {
        if(flag==XAResource.TMNOFLAGS)
            return null;
	return recoverList(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
   */
  private Xid [] recoverList(int flag) throws XAException{
        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(XAException e){
            throw e;
        }
        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 void commit(Xid xid, boolean flag) throws XAException{
        doRecovery(xid, true);
    }
    public void rollback(Xid xid) throws XAException{
        doRecovery(xid, false);
    }
  /**
   * 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
   */
  private void doRecovery(Xid xid, boolean isCommit) throws XAException{

        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) { }
        }
    }
    private static final char HEX_DIGITS[] = {
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        'A', 'B', 'C', 'D', 'E', 'F'
    };
  /**
   * Converts Xids into string that can be used in sql statements for oracle.
   *
   * @param abyte0[] a byte value
   * @return a String value
   */
  private static String toHexString(byte abyte0[]) {
        StringBuilder builder = new StringBuilder();
        if(null != abyte0 && 0 < abyte0.length) {
            for(int i = 0; i < abyte0.length; i++) {
                builder.append(HEX_DIGITS[(abyte0[i] & 0xf0) >> 4]);
                builder.append(HEX_DIGITS[abyte0[i] & 0xf]);
            }
            return builder.toString();
         } else {
            return "";
         }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy