KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jotm > JotmRecovery


1 /*
2  * @(#) JotmRecovery.java
3  *
4  * JOTM: Java Open Transaction Manager
5  *
6  *
7  * This module was originally developed by
8  *
9  * - Bull S.A. as part of the JOnAS application server code released in
10  * July 1999 (www.bull.com)
11  *
12  * --------------------------------------------------------------------------
13  * The original code and portions created by Bull SA are
14  * Copyright (c) 1999 BULL SA
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are met:
19  *
20  * -Redistributions of source code must retain the above copyright notice, this
21  * list of conditions and the following disclaimer.
22  *
23  * -Redistributions in binary form must reproduce the above copyright notice,
24  * this list of conditions and the following disclaimer in the documentation
25  * and/or other materials provided with the distribution.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  *
39  * --------------------------------------------------------------------------
40  * $Id: JotmRecovery.java,v 1.6 2005/05/03 23:19:46 tonyortiz Exp $
41  * --------------------------------------------------------------------------
42  */

43
44 package org.objectweb.jotm;
45
46 import java.nio.ByteBuffer JavaDoc;
47 import java.util.Vector JavaDoc;
48
49 import javax.transaction.xa.XAResource JavaDoc;
50 import javax.transaction.xa.Xid JavaDoc;
51
52 import org.objectweb.howl.log.xa.XALogRecord;
53 import org.objectweb.howl.log.xa.XACommittingTx;
54 import javax.transaction.xa.XAException JavaDoc;
55
56 /**
57  *
58  * @author Tony Ortiz
59  */

60
61 /**
62  * Thread class used to commit an Xid of an XAResource,
63  * XAResource.commit(Xid).
64  */

65
66 class commitXAResourceXid extends Thread JavaDoc {
67     XAResource JavaDoc commitxares = null;
68     Xid commitxid = null;
69     
70    commitXAResourceXid (XAResource JavaDoc pxares, Xid pxid) {
71        if (TraceTm.recovery.isDebugEnabled()) {
72            TraceTm.recovery.debug("pxares= " + pxares);
73            TraceTm.recovery.debug("pxid= " + pxid);
74        }
75        commitxares = pxares;
76        commitxid = pxid;
77    }
78     
79    public void run() {
80        if (TraceTm.recovery.isDebugEnabled()) {
81            TraceTm.recovery.debug("thread for commitXAResourceXid");
82            TraceTm.recovery.debug(" Committing xid= " + commitxid);
83            TraceTm.recovery.debug(" with XAResource= " + commitxares);
84        }
85
86
87        try {
88            commitxares.commit(commitxid, false);
89        } catch (XAException JavaDoc e) {
90            TraceTm.recovery.error("Unable to commit Xid during Recovery " + e.getMessage());
91        }
92    }
93 }
94
95 /**
96  * Thread class used to abort an Xid of an XAResource,
97  * XAResource.rollback(Xid).
98  */

99
100 class abortXAResourceXid extends Thread JavaDoc {
101     XAResource JavaDoc abortxares = null;
102     Xid abortxid = null;
103     
104     abortXAResourceXid (XAResource JavaDoc pxares, Xid pxid) {
105         if (TraceTm.recovery.isDebugEnabled()) {
106             TraceTm.recovery.debug("pxares= " + pxares);
107             TraceTm.recovery.debug("pxid= " + pxid);
108         }
109         abortxares = pxares;
110         abortxid = pxid;
111     }
112     
113     public void run() {
114         if (TraceTm.recovery.isDebugEnabled()) {
115             TraceTm.recovery.debug("thread for abortXAResourceXid");
116             TraceTm.recovery.debug(" Rolling Back xid= " + abortxid);
117             TraceTm.recovery.debug(" with XAResource= " + abortxares);
118         }
119         
120         try {
121             abortxares.rollback(abortxid);
122         } catch (XAException JavaDoc e) {
123             TraceTm.recovery.error("Unable to rollback Xid during Recovery " + e.getMessage());
124         }
125     }
126 }
127 /**
128  * Vector used to hold all Resource Managers that were
129  * registered when the system crashed, may have XIDs that
130  * need to be recovered.
131  */

132
133 class RecoverRmInfo {
134
135     private String JavaDoc recoverRm = null;
136     private byte[] recoverXares = null;
137     private String JavaDoc recoverxaresName = null;
138     private int recoverIndex = 0;
139
140     public void addRecoverRmXaRes (String JavaDoc rrmName, byte[] rrmXares, String JavaDoc rrmxaresName, int rrmIndex) {
141
142         if (TraceTm.recovery.isDebugEnabled()) {
143             TraceTm.recovery.debug("RecoverRm Resource Manager= " + rrmName);
144             TraceTm.recovery.debug("RecoverRm XAResource = " + new String JavaDoc(rrmXares));
145             TraceTm.recovery.debug("RecoverRm Index = " + rrmIndex);
146         }
147
148         recoverRm = rrmName;
149         recoverXares = rrmXares;
150         recoverxaresName = rrmxaresName;
151         recoverIndex = rrmIndex;
152     }
153
154     public String JavaDoc getRecoverRm () {
155         if (TraceTm.recovery.isDebugEnabled()) {
156             TraceTm.recovery.debug("recoverRm= " + recoverRm);
157         }
158         return recoverRm;
159     }
160
161     public byte[] getRecoverXaRes () {
162         if (TraceTm.recovery.isDebugEnabled()) {
163             TraceTm.recovery.debug("recoverXares= " + new String JavaDoc(recoverXares));
164         }
165         return recoverXares;
166     }
167     
168     public String JavaDoc getRecoverXaResName () {
169         if (TraceTm.recovery.isDebugEnabled()) {
170             TraceTm.recovery.debug("recoverXares= " + new String JavaDoc(recoverxaresName));
171         }
172         return recoverxaresName;
173     }
174     public int getRecoverIndex () {
175         if (TraceTm.recovery.isDebugEnabled()) {
176             TraceTm.recovery.debug("recoverIncex= " + recoverIndex);
177         }
178         return recoverIndex;
179     }
180 }
181
182 /**
183  * Vector and Array used to hold all Transactions that were
184  * in a commit pending status when the system crashed, these
185  * transactions (XIDs) may need to be recovered.
186  */

187
188 class TxxidRecovered {
189
190     private int txxidIndex = 0;
191     private byte[] txxidXares = null;
192     private String JavaDoc txxidXaresname = null;
193     private byte[] txxidXid = null;
194     private int txxidStatus = 0;
195     private int txxidAction = 0; // 0-Do nothing, implied already committed
196
// 1-Commit, 2-Rollback
197
private XAResource JavaDoc commitxares = null;
198     private Xid commitxid = null;
199
200     public void addXidInfo (int pindex, byte[] pxares, String JavaDoc pxaresname, byte[] pxid, int pstatus) {
201
202         if (TraceTm.recovery.isDebugEnabled()) {
203             TraceTm.recovery.debug("Txxid index= " + pindex);
204             TraceTm.recovery.debug("Txxid xares= " + new String JavaDoc(pxares));
205             TraceTm.recovery.debug("Txxid xid= " + new String JavaDoc(pxid));
206             TraceTm.recovery.debug("Txxid status= " + pstatus);
207         }
208
209         txxidIndex = pindex;
210         txxidXares = pxares;
211         txxidXaresname = pxaresname;
212         txxidXid = pxid;
213         txxidStatus = pstatus;
214     }
215
216     public int getRecoverindex () {
217         if (TraceTm.recovery.isDebugEnabled()) {
218             TraceTm.recovery.debug("txxidIndex= " + txxidIndex);
219         }
220         return txxidIndex;
221     }
222
223     public byte[] getRecoverxares () {
224         if (TraceTm.recovery.isDebugEnabled()) {
225             TraceTm.recovery.debug("txxidXares= " + new String JavaDoc(txxidXares));
226         }
227         return txxidXares;
228     }
229
230     public String JavaDoc getRecoverxaresname () {
231         if (TraceTm.recovery.isDebugEnabled()) {
232             TraceTm.recovery.debug("txxidXaresname= " + txxidXaresname);
233         }
234         return txxidXaresname;
235     }
236
237     public byte[] getRecoverxid () {
238         if (TraceTm.recovery.isDebugEnabled()) {
239             TraceTm.recovery.debug("txxidXid= " + new String JavaDoc(txxidXid));
240         }
241         return txxidXid;
242     }
243
244     public int getRecoverstatus () {
245         if (TraceTm.recovery.isDebugEnabled()) {
246             TraceTm.recovery.debug("txxidStatus= " + txxidStatus);
247         }
248         return txxidStatus;
249     }
250     
251     public void setRecoverstatus (int pstatus) {
252         if (TraceTm.recovery.isDebugEnabled()) {
253             TraceTm.recovery.debug("pstatus= " + pstatus);
254         }
255         txxidStatus = pstatus;
256     }
257     
258     public int getRecoveraction () {
259         if (TraceTm.recovery.isDebugEnabled()) {
260             TraceTm.recovery.debug("txxidAction= " + txxidAction);
261         }
262         return txxidAction;
263     }
264     
265     public void setRecoveraction (int paction) {
266         if (TraceTm.recovery.isDebugEnabled()) {
267             TraceTm.recovery.debug("paction= " + paction);
268         }
269         txxidAction = paction;
270     }
271     
272     public XAResource JavaDoc getCommitxares () {
273         return commitxares;
274     }
275     
276     public void setCommitxares (XAResource JavaDoc pcommitxares) {
277         commitxares = pcommitxares;
278     }
279     
280     public Xid getCommitxid () {
281         return commitxid;
282     }
283     
284     public void setCommitxid (Xid pcommitxid) {
285         commitxid = pcommitxid;
286     }
287 }
288
289 class TxRecovered {
290     private long recoverydatetime = 0L;
291     private byte[] txxid = null;
292     private String JavaDoc txdatetime = null;
293     private int xidcount = 0;
294     private XACommittingTx xacommittingtx = null;
295
296     private TxxidRecovered [] xidinfo;
297
298     public void addtxrecovered (long prdt, byte[] ptxxid, String JavaDoc ptdt, int pxcnt, XACommittingTx pxacmtx) {
299
300         if (TraceTm.recovery.isDebugEnabled()) {
301             TraceTm.recovery.debug("Recover tx prdt= " + prdt);
302             TraceTm.recovery.debug("Recover tx ptxxid= " + new String JavaDoc(ptxxid));
303             TraceTm.recovery.debug("Recover tx ptdt= " + ptdt);
304             TraceTm.recovery.debug("Recover tx pxcnt= " + pxcnt);
305             TraceTm.recovery.debug("Recover tx pxacmtx= " + pxacmtx);
306         }
307
308         recoverydatetime = prdt;
309         txxid = ptxxid;
310         txdatetime = ptdt;
311         xidcount = pxcnt;
312         xacommittingtx = pxacmtx;
313
314         xidinfo = new TxxidRecovered [xidcount];
315     }
316
317     public void addRecoverTxXidInfo (TxxidRecovered ptxxidr, int rindx) {
318
319         if (TraceTm.recovery.isDebugEnabled()) {
320             TraceTm.recovery.debug("addRecoverTxXidInfo");
321         }
322         xidinfo[rindx] = ptxxidr;
323     }
324     public long getrecoverdatetime () {
325         return recoverydatetime;
326     }
327     
328     public byte [] gettxxid () {
329         return txxid;
330     }
331     
332     public String JavaDoc gettxdatetime () {
333         return txdatetime;
334     }
335     
336     public int getxidcount () {
337         return xidcount;
338     }
339     
340     public TxxidRecovered getRecoverTxXidInfo (int rindx) {
341
342         if (TraceTm.recovery.isDebugEnabled()) {
343             TraceTm.recovery.debug("getRecoverTxXidInfo");
344         }
345         return xidinfo[rindx];
346     }
347     
348     public XACommittingTx getXACommittingTx () {
349         if (TraceTm.recovery.isDebugEnabled()) {
350             TraceTm.recovery.debug("getXACommittingTx");
351         }
352         return xacommittingtx;
353     }
354 }
355
356 public class JotmRecovery {
357     
358     private static JotmRecovery unique = null;
359     private static Vector JavaDoc vTxRecovered = new Vector JavaDoc ();
360     private static Vector JavaDoc vRecoverRmInfo = new Vector JavaDoc ();
361     private Vector JavaDoc userRecoveryRecords = new Vector JavaDoc ();
362     
363     /**
364      * Constructor.
365      */

366
367     public JotmRecovery(){
368
369         if (TraceTm.recovery.isDebugEnabled()) {
370             TraceTm.recovery.debug("JotmRecovery constructor");
371         }
372
373         unique = this;
374     }
375     
376     /**
377      * Returns the unique instance of the class or <code>null</code> if not
378      * initialized.
379      *
380      * @return The <code>JotmRecovery</code> object created
381      */

382
383     public static JotmRecovery getJotmRecovery() {
384
385         return unique;
386     }
387     
388     /**
389      * Returns the unique instance of the class or <code>null</code> if not
390      * initialized.
391      *
392      * @return The <code>TxRecovered</code> vector created
393      */

394
395     public static Vector JavaDoc getTxRecovered() {
396
397         return vTxRecovered;
398     }
399     
400     /**
401      * Returns the unique instance of the class or <code>null</code> if not
402      * initialized.
403      *
404      * @return The <code>RecoverRmInfo</code> vector created
405      */

406
407     public static Vector JavaDoc getRecoverRmInfo() {
408
409         return vRecoverRmInfo;
410     }
411     
412     /**
413      * Returns the index of the Resource Manager's XAResource.
414      *
415      * @return Index of the Resource Manager's XAResource.
416      */

417
418     public int getRmIndex(byte [] pxares) {
419         int numRm = vRecoverRmInfo.size();
420         RecoverRmInfo myrecoverRmInfo;
421         
422         for (int i=0; i<numRm; i++){
423             myrecoverRmInfo = (RecoverRmInfo) vRecoverRmInfo.elementAt(i);
424             byte [] inrmxares = myrecoverRmInfo.getRecoverXaRes();
425             
426             if (TraceTm.recovery.isDebugEnabled()) {
427                 TraceTm.recovery.debug("XAResource param " + pxares);
428                 TraceTm.recovery.debug("XAResource in rm " + inrmxares);
429             }
430
431             if (inrmxares == pxares) {
432                 return myrecoverRmInfo.getRecoverIndex();
433             }
434         }
435         return 99;
436     }
437
438     public Vector JavaDoc getUserRecoveryVector() { // currently used by test suite
439
return userRecoveryRecords;
440     }
441     
442     /**
443      * Processes an XACOMMIT entry (putCommit) that does not have an associated
444      * XADONE entry (putDone).
445      *
446      * @param lr LogRecord that was passed to onRecord() method.
447      */

448
449     public void rebuildTransaction (XALogRecord lr) {
450
451         if (TraceTm.recovery.isDebugEnabled()) {
452             TraceTm.recovery.debug("rebuildTransaction");
453         }
454         
455         RecoverRmInfo myrecoverRmInfo = null;
456         TxxidRecovered myrecoverTxInfo = null;
457         TxRecovered mytxRecovered = null;
458         
459         // Temporary Recovery Record
460
byte [] tempRec;
461         byte [] rt = new byte [3]; // Applies to all Records
462

463         // Resource Manager Record Type 1 fields
464
long rmdatetime;
465         int rmcount;
466
467         // Resource Manager Record Type 2
468
byte [] resmgr2;
469
470         // Resource Manager Record Type 2 fields
471
int rmlength;
472         byte [] rmname = null;
473         int rmxareslength;
474         byte [] rmxares = null;
475         int rmindx;
476
477         // Recovery Record Type 1 fields
478
long rcdatetime;
479         int txxidlength;
480         byte [] txXid = null;
481         int txdatelength;
482         byte [] txdatetime;
483         int xarescount = 0;
484
485         // Check if there already exist a recovery record in our array with the
486
// same txXid but a older datetime. If so remove it and store this one,
487
// otherwise throw this one away.
488

489         // Recovery Record Type 2
490
byte [] recov2;
491
492         // Recovery Record Type 2 fields
493
byte [] rt2 = new byte [3];
494         int xaresindex;
495         int xareslength;
496         int xaresnamelength;
497         byte [] xares;
498         int xidlength;
499         byte [] xaresname;
500         byte [] recoveryxid;
501         int xidstatus;
502
503         String JavaDoc trt;
504         
505         XACommittingTx myxacommittx = lr.getTx();
506         tempRec = lr.getFields() [0];
507
508         ByteBuffer JavaDoc rr = ByteBuffer.wrap(tempRec);
509
510         rr.get(rt, 0, 3);
511         trt = new String JavaDoc (rt);
512
513         if (TraceTm.recovery.isDebugEnabled()) {
514             TraceTm.recovery.debug("Recovery Record type= " + trt);
515         }
516
517         if (trt.equals("RM1")) {
518
519             rmdatetime = rr.getLong();
520             rmcount = rr.getInt();
521
522             if (TraceTm.recovery.isDebugEnabled()) {
523                 TraceTm.recovery.debug("Resource Manager count= " + rmcount);
524             }
525
526             for (int i=1; i <= rmcount; i++) {
527                 resmgr2 = lr.getFields()[i];
528
529                 ByteBuffer JavaDoc resm2 = ByteBuffer.wrap(resmgr2);
530                 resm2.get(rt2, 0, 3);
531                 trt = new String JavaDoc (rt2);
532
533                 if (trt.equals("RM2")) {
534                     rmlength = resm2.getInt();
535                     rmname = new byte[rmlength];
536                     resm2.get(rmname, 0, rmlength);
537                     xareslength = resm2.getInt();
538                     xares = new byte[xareslength];
539                     resm2.get(xares, 0, xareslength);
540                     xaresnamelength = resm2.getInt();
541                     xaresname = new byte[xaresnamelength];
542                     resm2.get(xaresname, 0, xaresnamelength);
543                     rmindx = resm2.getInt();
544
545                     String JavaDoc myrmname = new String JavaDoc(rmname);
546                     String JavaDoc myxares = new String JavaDoc(xares);
547                     String JavaDoc myxaresname = new String JavaDoc(xaresname);
548                     myrecoverRmInfo = new RecoverRmInfo();
549
550                     myrecoverRmInfo.addRecoverRmXaRes (myrmname, xares, myxaresname, rmindx);
551                     vRecoverRmInfo.addElement(myrecoverRmInfo);
552                 }
553             }
554         }
555         else if (trt.equals("RR1")) {
556                 rcdatetime = rr.getLong();
557                 txxidlength = rr.getInt();
558                 txXid = new byte[txxidlength];
559                 rr.get(txXid, 0, txxidlength);
560                 txdatelength = rr.getInt();
561                 txdatetime = new byte[txdatelength];
562                 rr.get(txdatetime, 0, txdatelength);
563                 xarescount = rr.getInt();
564
565                 String JavaDoc mytxXid = new String JavaDoc(txXid);
566                 String JavaDoc mytxdatetime = new String JavaDoc(txdatetime);
567
568                 mytxRecovered = new TxRecovered();
569
570                 if (TraceTm.recovery.isDebugEnabled()) {
571                     TraceTm.recovery.debug("XAResource count= " + xarescount);
572                 }
573
574                 mytxRecovered.addtxrecovered (rcdatetime, txXid, mytxdatetime, xarescount, myxacommittx);
575                 
576                 for (int i=1; i <= xarescount; i++) {
577                     myrecoverTxInfo = new TxxidRecovered();
578                     recov2 = lr.getFields()[i];
579
580                     ByteBuffer JavaDoc rr2 = ByteBuffer.wrap(recov2);
581                     rr2.get(rt2, 0, 3);
582                     trt = new String JavaDoc (rt2);
583
584                     if (trt.equals("RR2")) {
585                         xaresindex = rr2.getInt();
586                         xareslength = rr2.getInt();
587                         xares = new byte[xareslength];
588                         rr2.get(xares, 0, xareslength);
589                         xaresnamelength = rr2.getInt();
590                         xaresname = new byte[xaresnamelength];
591                         rr2.get(xaresname, 0, xaresnamelength);
592                         xidlength = rr2.getInt();
593                         recoveryxid = new byte[xidlength];
594                         rr2.get(recoveryxid, 0, xidlength);
595                         xidstatus = rr2.getInt();
596
597                         String JavaDoc myxares = new String JavaDoc(xares);
598                         String JavaDoc myxaresname = new String JavaDoc(xaresname);
599                         String JavaDoc myrecoveryxid = new String JavaDoc(recoveryxid);
600
601                         myrecoverTxInfo.addXidInfo (xaresindex, xares, myxaresname, recoveryxid, xidstatus);
602                         mytxRecovered.addRecoverTxXidInfo (myrecoverTxInfo, i-1);
603                     }
604                 }
605                 vTxRecovered.addElement(mytxRecovered);
606         }
607         else if (trt.equals("RU1")) {
608                 XidImpl.setUuids( rr.getLong(), rr.getLong());
609         }
610         else {
611             if (TraceTm.recovery.isDebugEnabled()) {
612                 TraceTm.recovery.debug("Unknown record type during replay = " + trt);
613             }
614             // add this byteBuffer of this record to a vector for user recovery
615
rr.rewind();
616             userRecoveryRecords.add( rr );
617             userRecoveryRecords.add( myxacommittx );
618         }
619     }
620
621     public void recoverTransactions (Vector JavaDoc rmreg) throws XAException JavaDoc {
622         if (TraceTm.recovery.isDebugEnabled()) {
623             TraceTm.recovery.debug("recoverTransactions");
624         }
625
626         RmRegistration myregisteredRmInfo = null;
627         String JavaDoc myregrm = null;
628         XAResource JavaDoc myregxares = null;
629         int rmregsize = rmreg.size(); // number of Resource Managers registered
630

631         RecoverRmInfo myrecoverRmInfo = null;
632         String JavaDoc myrm = null;
633         byte[] byxares = null;
634
635         int rcflag = 0;
636
637         // read the tmRecovered object and determine if any of the xaResources
638
// require recovery (xares.recover call)
639

640         int rmsize = vRecoverRmInfo.size(); // number of Resource Managers when system crashed
641

642         if (rmsize == 0) {
643             if (TraceTm.recovery.isDebugEnabled()) {
644                 TraceTm.recovery.debug("Nothing to recover");
645             }
646             return;
647         }
648
649         if (TraceTm.recovery.isDebugEnabled()) {
650             TraceTm.recovery.debug("number Resource Manager recover= " + rmsize);
651         }
652
653         // we can only recover Resource Managers that are in our log
654
// (RecoverRmInfo) and have been registered (RmRegistered)
655

656         for (int i=0; i<rmregsize; i++) {
657             
658             RmRegistration myrmreg = (RmRegistration) rmreg.elementAt(i);
659             myregrm = myrmreg.rmGetName();
660             
661             // checkout the XAResource, this will "lock" the XAResource
662
// must checkin later
663
myregxares = myrmreg.rmCheckoutXARes();
664
665             for (int j=0; j<rmsize; j++) {
666                 myrecoverRmInfo = (RecoverRmInfo) vRecoverRmInfo.elementAt(j);
667                 myrm = myrecoverRmInfo.getRecoverRm();
668                 byxares = myrecoverRmInfo.getRecoverXaRes();
669                 
670                 if (TraceTm.recovery.isDebugEnabled()) {
671                     TraceTm.recovery.debug("Registered Resource Manager " + myregrm);
672                     TraceTm.recovery.debug("Registered XAResource " + myregxares);
673                     TraceTm.recovery.debug("Recover Resource Manager " + myrm);
674                     TraceTm.recovery.debug("Recover XAResource " + new String JavaDoc(byxares));
675                 }
676                 
677                 if (myregrm.equals(myrm)){
678                     Xid [] javaxid;
679                     
680                     try {
681                         // recover returns javax.transaction.xa.Xid objects
682
// we must cast to org.objectweb.jotm.Xid objects
683
javaxid = myregxares.recover(rcflag);
684                     } catch (XAException JavaDoc e) {
685                         throw new XAException JavaDoc("xaResource.recover call failed during recovery " + e.getMessage());
686                     }
687                     
688                     if (javaxid == null) {
689                         if (TraceTm.recovery.isDebugEnabled()) {
690                             TraceTm.recovery.debug("No XIDs to recover for Xares javaxid is null");
691                         }
692                         break;
693                     }
694                     
695                     if (TraceTm.recovery.isDebugEnabled()) {
696                         TraceTm.recovery.debug("javaxid size= " + javaxid.length);
697                     }
698                     
699                     if (javaxid.length == 0) {
700                         if (TraceTm.recovery.isDebugEnabled()) {
701                             TraceTm.recovery.debug("No XIDs to recover for Xares= "+ myregxares);
702                         }
703                         break;
704                     }
705                     
706                     // set the action required for the XIDs located in our
707
// txxidRecovered (array), pointed to by TxRecovered (vector)
708
settxxidrecoveraction (myregxares, javaxid);
709                     break;
710                 }
711             }
712             
713             // checkin the XAResource, this will "unlock" the XAResource
714
myrmreg.rmCheckinXARes();
715         }
716         
717         // We can now walk through TxRecovered and perform the action on
718
// each of the Xids stored in TxxidRecovered.
719

720         doActionXidRecover ();
721         
722         // We can now walk through TxRecovered and delete (howl done) any TxRecovered
723
// entries that have had all their Xids (TxxidRecovered) committed or rolled
724
// back successfully.
725
// If any Xids have not been committed or rolledback, create a new TxRecovered
726
// entry (howl commit) with the Xids (TxxidRecovered) that are still pending.
727

728         doCleanupXidRecover ();
729     }
730
731     private void settxxidrecoveraction (XAResource JavaDoc actxares, Xid [] actionxid) {
732         if (TraceTm.recovery.isDebugEnabled()) {
733             TraceTm.recovery.debug("settxxidrecoveraction");
734         }
735         
736         TxxidRecovered mytxxidRecovered = null;
737         TxRecovered mytxRecovered = null;
738
739         for (int i=0; i<actionxid.length; i++) {
740             boolean xidfound = false;
741             Xid myjavaxid = actionxid[i];
742             org.objectweb.jotm.Xid myxid = new XidImpl(myjavaxid);
743             byte [] mybrqu = myxid.getBranchQualifier();
744                 
745             for (int j=0; j<vTxRecovered.size(); j++){
746                 mytxRecovered = (TxRecovered) vTxRecovered.elementAt(j);
747                     
748                 if (mytxRecovered != null) {
749                     
750                     for (int k=0; k<mytxRecovered.getxidcount(); k++){
751                         mytxxidRecovered = mytxRecovered.getRecoverTxXidInfo(k);
752                         
753                         if (mytxxidRecovered != null) {
754                             byte [] mytxxid = mytxxidRecovered.getRecoverxid();
755                             org.objectweb.jotm.Xid mymytxxid = new XidImpl(mytxxid);
756                                 
757                             if (mymytxxid.IsThisOneOfOurs(mybrqu)) {
758                                     
759                                 if (TraceTm.recovery.isDebugEnabled()) {
760                                     TraceTm.recovery.debug("mymytxxid= " + mymytxxid.toString(true));
761                                     TraceTm.recovery.debug("myxid = " + myxid.toString(true));
762                                 }
763                         
764                                 if ((new String JavaDoc(mytxxid)).equals(myxid.toString(true))){
765                                     xidfound = true;
766                                     int myaction = 1; // Commit
767
mytxxidRecovered.setRecoveraction(myaction);
768                                     mytxxidRecovered.setCommitxares(actxares);
769                                     mytxxidRecovered.setCommitxid(myjavaxid);
770                                     mytxRecovered.addRecoverTxXidInfo(mytxxidRecovered,k);
771                                     break;
772                                 }
773                             } else {
774                                 if (TraceTm.recovery.isDebugEnabled()) {
775                                     TraceTm.recovery.debug("Xid is not one of ours");
776                                 }
777                             }
778                         }
779                     }
780                         
781                     if (xidfound) { // xid found in a TxxidRecovered of the TxRecovered vector
782
break;
783                     }
784                 }
785                     
786                 if (xidfound) { // xid found in a TxxidRecovered of the TxRecovered vector
787
break;
788                 } else { // xid not found in any TxxidRecovered of the TxRecovered vector
789
abortimmediate (actxares, myjavaxid);
790                 }
791             }
792         }
793     }
794
795     private void doActionXidRecover () {
796         if (TraceTm.recovery.isDebugEnabled()) {
797             TraceTm.recovery.debug("doActionXidRecover");
798         }
799         
800         TxxidRecovered mytxxidRecovered = null;
801         TxRecovered mytxRecovered = null;
802         
803         for (int i=0; i<vTxRecovered.size(); i++){
804             mytxRecovered = (TxRecovered) vTxRecovered.elementAt(i);
805             XAResource JavaDoc commitxares = null;
806             Xid commitxid = null;
807             
808             for (int j=0; j<mytxRecovered.getxidcount(); j++){
809                 mytxxidRecovered = mytxRecovered.getRecoverTxXidInfo(j);
810                 
811                 if (mytxxidRecovered != null) {
812
813                     // If action = 0; XAResource is known but the XID associated
814
// to is was not returned in the xares.recover call. This implies
815
// that the XID was already committed, just ignore.
816
// If action = 1; XAResource is known and the xares.recover call
817
// returned the specifed XID. This implies that we should attempt
818
// to commit the XID (if possible).
819

820                     if (mytxxidRecovered.getRecoveraction() == 1) { // Commit
821
byte [] myrcxid = mytxxidRecovered.getRecoverxid();
822                         commitxares = mytxxidRecovered.getCommitxares();
823                         commitxid = mytxxidRecovered.getCommitxid();
824             
825                         new commitXAResourceXid (commitxares, commitxid).start();
826                     }
827                 }
828             }
829         }
830     }
831
832     private void abortimmediate (XAResource JavaDoc abortxares, Xid abortxid) {
833         if (TraceTm.recovery.isDebugEnabled()) {
834             TraceTm.recovery.debug("abortimmediate");
835         }
836
837         new abortXAResourceXid (abortxares, abortxid).start();
838     }
839     
840     private void doCleanupXidRecover () {
841         if (TraceTm.recovery.isDebugEnabled()) {
842             TraceTm.recovery.debug("doCleanupXidRecover");
843         }
844         
845         TxxidRecovered myTxxidRecovered = null;
846         TxRecovered mytxRecovered = null;
847         
848         // for (int i=0; i<vTxRecovered.size(); i++){
849
// We must go upward (last element to first) since we may remove
850
// elements of the vTxRecovered vector.
851

852         if (TraceTm.recovery.isDebugEnabled()) {
853             TraceTm.recovery.debug("vTxRecovered.size= " +vTxRecovered.size());
854         }
855         
856         for (int i=vTxRecovered.size()-1; i>=0; i--) {
857             boolean possibleheuristic = false;
858             XACommittingTx myxacommittingtx = null;
859             mytxRecovered = (TxRecovered) vTxRecovered.elementAt(i);
860             
861             if (TraceTm.recovery.isDebugEnabled()) {
862                 TraceTm.recovery.debug("mytxRecovered.xidcount= " +mytxRecovered.getxidcount());
863             }
864             
865             for (int j=0; j<mytxRecovered.getxidcount(); j++){
866                 myTxxidRecovered = mytxRecovered.getRecoverTxXidInfo(j);
867                 
868                 if (myTxxidRecovered != null) {
869                     if ((myTxxidRecovered.getRecoveraction() == 0) || // Xid already committed, ignore
870
(myTxxidRecovered.getRecoveraction() == 1)) { // Xid just committed
871
;
872                     } else {
873                         if (TraceTm.recovery.isDebugEnabled()) {
874                             TraceTm.recovery.debug("possibleheuristic");
875                         }
876                         
877                         possibleheuristic = true;
878                     }
879                 }
880             }
881             
882             // We cannot remove the vTxRecovered vector element if there
883
// exists the possibility of a heuristic transaction.
884

885             if (!possibleheuristic) {
886
887                 if (TraceTm.recovery.isDebugEnabled()) {
888                     TraceTm.recovery.debug("write howlDonelog");
889                 }
890                 
891                 myxacommittingtx = mytxRecovered.getXACommittingTx();
892                 byte [] rmDone = new byte [11];
893                 byte [] [] rmDoneRecord = new byte [1] [11];
894
895                 rmDone = "RR3JOTMDONE".getBytes();
896
897                 try {
898                     rmDoneRecord [0] = rmDone;
899                     TransactionRecoveryImpl.getTransactionRecovery().howlDoneLog (rmDoneRecord, myxacommittingtx);
900                 } catch (Exception JavaDoc f) {
901                     String JavaDoc howlerror =
902                         "Cannot howlDoneLog:"
903                         + f
904                         + "--"
905                         + f.getMessage();
906                     TraceTm.jotm.error("Got LogException from howlDoneLog: "+ howlerror);
907                 }
908
909                 if (TraceTm.recovery.isDebugEnabled()) {
910                     TraceTm.recovery.debug("remove txRecovered entry");
911                 }
912                 vTxRecovered.remove(i);
913             }
914         }
915     }
916 }
Popular Tags