KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > transaction > OracleXAResource


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 //Source File Name: OracleXAResource.java
25

26 package com.sun.enterprise.transaction;
27
28 import java.sql.*;
29 import javax.transaction.xa.*;
30
31 import com.sun.enterprise.util.i18n.StringManager;
32 import java.util.logging.Logger JavaDoc;
33 import java.util.logging.Level JavaDoc;
34 import com.sun.logging.LogDomains;
35
36
37 /**
38  * This implements workaround for Oracle XAResource. Oracle's 8.1.7 XAResource implementation
39  * doesn't work fine while recovery. This class fires sql statements to achieve same.
40  *
41  * @author <a HREF="mailto:bala.dutt@sun.com">Bala Dutt</a>
42  * @version 1.0
43  */

44 public class OracleXAResource extends XAResourceWrapper
45 {
46
47     // Sting Manager for Localization
48
private static StringManager sm = StringManager.getManager(OracleXAResource.class);
49     private static Logger JavaDoc _logger = LogDomains.getLogger(LogDomains.JTA_LOGGER);
50
51     
52   /**
53    * Recovers list of xids in transaction table. Recover on oracle ignores flags sent to it, this method
54    * takes care of flags in addition to calling recoverList for xid list.
55    *
56    * @param flag an <code>int</code> value
57    * @return a <code>Xid[]</code> value
58    * @exception XAException if an error occurs
59    */

60     private static int called=1;
61     public Xid[] recover(int flag) throws XAException {
62         called++;
63         if(flag==XAResource.TMNOFLAGS)
64             return null;
65     return recoverList(flag);
66     }
67   /**
68    * Fires a select statement so that transaction xids are updated and retrieve the xid list. Oracle
69    * doesn't update the xid's for sometime. After this update, recover of real oracle xa resource is
70    * is used get xid list.
71    *
72    * @return a <code>Xid[]</code> value
73    * @exception XAException if an error occurs
74    */

75   private Xid [] recoverList(int flag) throws XAException{
76         Statement stmt = null;
77         ResultSet resultset = null;
78         Connection con = null;
79         try{
80             con=(Connection)m_xacon.getConnection(subject,null);
81             if(null == con)
82                 // throw new XAException("Oracle XA Resource wrapper : connection could not be got");
83
throw new XAException(sm.getString("transaction.oracle_xa_wrapper_connection_failed"));
84             stmt = con.createStatement();
85             resultset = stmt.executeQuery(
86                 "select pending.local_tran_id from SYS.PENDING_TRANS$ pending, SYS.DBA_2PC_NEIGHBORS");
87             resultset.close();
88             resultset = null;
89             stmt.close();
90             stmt=null;
91             return m_xacon.getXAResource().recover(flag);
92         }
93         catch(SQLException sqlexception){
94             //Trace.info("Failed to recover xid list");
95
// throw new XAException("oracle XA Resource wrapper : "+sqlexception);
96
throw new XAException(sm.getString("transaction.oracle_sqlexception_occurred",sqlexception));
97         }
98         catch(Exception JavaDoc e){
99             throw new XAException(sm.getString("transaction.oracle_unknownexception_occurred",e));
100             // throw new XAException("oracle XA Resource wrapper : "+e);
101
}
102         finally{
103             if(null != resultset)
104                 try{
105                     resultset.close();
106                 }
107                 catch(SQLException sqlexception1) { }
108             if(null != stmt)
109                 try{
110                     stmt.close();
111                 }
112                 catch(SQLException sqlexception2) { }
113         }
114     }
115     public void commit(Xid xid, boolean flag) throws XAException{
116         doRecovery(xid, true);
117     }
118     public void rollback(Xid xid) throws XAException{
119         doRecovery(xid, false);
120     }
121   /**
122    * Does actual recovery depending on boolean argument - true for commmit.
123    *
124    * @param xid a <code>Xid</code> value
125    * @param isCommit a <code>boolean</code> value
126    * @exception XAException if an error occurs
127    */

128   private void doRecovery(Xid xid, boolean isCommit) throws XAException{
129
130         try {
131             if (isCommit)
132                 m_xacon.getXAResource().commit(xid,true);
133             else
134                 m_xacon.getXAResource().rollback(xid);
135         } catch (XAException ex) {
136             _logger.log(Level.FINEST," An XAException occurred while calling XAResource method " , ex);
137         } catch (Exception JavaDoc ex) {
138             _logger.log(Level.FINEST," An Exception occurred while calling XAResource method " , ex);
139         }
140
141         Statement stmt = null;
142         ResultSet resultset = null;
143         Connection con = null;
144         try{
145             con=(Connection)m_xacon.getConnection(subject,null);
146             if(null == con)
147                 throw new XAException(sm.getString("transaction.oracle_xa_wrapper_connection_failed"));
148                 // throw new XAException("Oracle XA Resource wrapper : connection could not be got");
149
stmt = con.createStatement();
150             resultset = stmt.executeQuery(
151                 "select pending.local_tran_id from SYS.PENDING_TRANS$ pending, SYS.DBA_2PC_NEIGHBORS dba where pending.global_foreign_id = '"
152                 + toHexString(xid.getGlobalTransactionId()) +
153                 "' and pending.local_tran_id = dba.local_tran_id and dba.branch = '"
154                 + toHexString(xid.getBranchQualifier()) +
155                 "' and pending.state = 'prepared'");
156             if(resultset.next()){
157                 String JavaDoc s = resultset.getString(1);
158                 resultset.close();
159                 resultset = null;
160                 stmt.executeUpdate((isCommit ? "commit force '" : "rollback force '") + s + "'");
161                 stmt.close();
162                 stmt=null;
163             }
164         }
165         catch(SQLException sqlexception){
166             //Trace.info("Failed to recover " + xid+" "+ sqlexception);
167
_logger.log(Level.FINE," An SQLException during recovery " , sqlexception);
168             throw new XAException(sm.getString("transaction.oracle_sqlexception_occurred",sqlexception));
169             // throw new XAException("oracle XA Resource wrapper : "+sqlexception);
170
}
171         catch(Exception JavaDoc e){
172             //Trace.info("Exception while RecoveryTestRI recover "+e);
173
_logger.log(Level.FINE," An Exception during recovery " , e);
174             throw new XAException(sm.getString("transaction.oracle_unknownexception_occurred",e));
175             // throw new XAException("oracle XA Resource wrapper : "+e);
176
}
177         finally{
178             if(null != resultset)
179                 try{
180                     resultset.close();
181                 }
182                 catch(SQLException sqlexception1) { }
183             if(null != stmt)
184                 try{
185                     stmt.close();
186                 }
187                 catch(SQLException sqlexception2) { }
188         }
189     }
190     private static final char HEX_DIGITS[] = {
191         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
192         'A', 'B', 'C', 'D', 'E', 'F'
193     };
194   /**
195    * Converts Xids into string that can be used in sql statements for oracle.
196    *
197    * @param abyte0[] a <code>byte</code> value
198    * @return a <code>String</code> value
199    */

200   private static String JavaDoc toHexString(byte abyte0[]) {
201         StringBuffer JavaDoc stringbuffer = new StringBuffer JavaDoc();
202         if(null != abyte0 && 0 < abyte0.length) {
203             for(int i = 0; i < abyte0.length; i++) {
204                 stringbuffer.append(HEX_DIGITS[(abyte0[i] & 0xf0) >> 4]);
205                 stringbuffer.append(HEX_DIGITS[abyte0[i] & 0xf]);
206             }
207             return stringbuffer.toString();
208          } else {
209             return "";
210          }
211     }
212 }
213
Popular Tags