Source Code Cross Referenced for Current.java in  » Database-JDBC-Connection-Pool » jotm-2.0.10 » org » objectweb » jotm » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database JDBC Connection Pool » jotm 2.0.10 » org.objectweb.jotm 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * @(#) Current.java
0003:         *
0004:         * JOTM: Java Open Transaction Manager 
0005:         *
0006:         *
0007:         * This module was originally developed by 
0008:         *
0009:         *  - Bull S.A. as part of the JOnAS application server code released in 
0010:         *    July 1999 (www.bull.com)
0011:         * --------------------------------------------------------------------------
0012:         *  The original code and portions created by Bull SA are 
0013:         *  Copyright (c) 1999 BULL SA  
0014:         *  All rights reserved.
0015:         *  
0016:         * Redistribution and use in source and binary forms, with or without 
0017:         * modification, are permitted provided that the following conditions are met:
0018:         *
0019:         * -Redistributions of source code must retain the above copyright notice, this
0020:         * list of conditions and the following disclaimer. 
0021:         *
0022:         * -Redistributions in binary form must reproduce the above copyright notice, 
0023:         * this list of conditions and the following disclaimer in the documentation 
0024:         * and/or other materials provided with the distribution. 
0025:         *
0026:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
0027:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
0028:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
0029:         * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
0030:         * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
0031:         * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
0032:         * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
0033:         * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
0034:         * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
0035:         * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
0036:         * POSSIBILITY OF SUCH DAMAGE.
0037:         * -------------------------------------------------------------------------- 
0038:         *
0039:         * Contributor(s):
0040:         * 01/11/06 Christophe Ney cney@batisseurs.com 
0041:         *          Added ResourceManagerListener mechanism to remove ThreadData
0042:         *          dependency.
0043:         * 01/12/03 Dean Jennings - synchronizedMap for txXids
0044:         *
0045:         * --------------------------------------------------------------------------
0046:         * $Id: Current.java,v 1.54 2005/05/12 14:06:26 tonyortiz Exp $
0047:         * --------------------------------------------------------------------------
0048:         */
0049:        package org.objectweb.jotm;
0050:
0051:        import java.io.Serializable;
0052:        import java.util.Collections;
0053:        import java.util.Date;
0054:        import java.util.EmptyStackException;
0055:        import java.util.HashMap;
0056:        import java.util.Iterator;
0057:        import java.util.List;
0058:        import java.util.Map;
0059:        import java.util.Set;
0060:        import java.util.Stack;
0061:        import java.util.Vector;
0062:
0063:        import javax.naming.NamingException;
0064:        import javax.naming.Reference;
0065:        import javax.naming.Referenceable;
0066:        import javax.naming.StringRefAddr;
0067:        import javax.resource.spi.XATerminator;
0068:        import javax.transaction.HeuristicMixedException;
0069:        import javax.transaction.HeuristicRollbackException;
0070:        import javax.transaction.InvalidTransactionException;
0071:        import javax.transaction.NotSupportedException;
0072:        import javax.transaction.RollbackException;
0073:        import javax.transaction.Status;
0074:        import javax.transaction.SystemException;
0075:        import javax.transaction.Transaction;
0076:        import javax.transaction.UserTransaction;
0077:        import javax.transaction.xa.XAException;
0078:        import javax.transaction.xa.XAResource;
0079:
0080:        import org.objectweb.transaction.jta.ResourceManagerEvent;
0081:        import org.objectweb.transaction.jta.TransactionManager;
0082:        import org.objectweb.howl.log.xa.XACommittingTx;
0083:
0084:        /**
0085:         * <code>Current</code> is the common implementation for both
0086:         * <code>UserTransaction</code> and <code>TransactionManager</code>.
0087:         * <ul> 
0088:         * <li><code>UserTransaction</code> is used by clients that want to demarcate
0089:         * transactions themselves. It is referenceable through JNDI.</li>
0090:         * <li><code>TransactionManager</code> is used by an application server.</li>
0091:         * </ul>
0092:         * 
0093:         * <p>This object is unique in a VM, i. e. each application server has
0094:         * <em>ONE</em> <code>Current</code> object and each client program should
0095:         * normally issue only <em>ONE</em> lookup on JNDI.</p>
0096:         * 
0097:         * <p><code>Current</code> also implements <code>Referenceable</code> and
0098:         * <code>Serializable</code> because of JNDI.</p>
0099:         */
0100:
0101:        public class Current implements  UserTransaction, TransactionManager,
0102:                Referenceable, Serializable {
0103:
0104:            // transaction associated to the thread
0105:            // Thread specific data
0106:            private transient static ThreadLocal threadTx = new ThreadLocal();
0107:
0108:            // ------------------------------------------------------------------
0109:            // Private data
0110:            // ------------------------------------------------------------------
0111:
0112:            // Static hashtable: Xid ---> transaction
0113:            private transient static Map txXids = Collections
0114:                    .synchronizedMap(new HashMap());
0115:
0116:            // Must be init at null, for clients that do not get UserTransaction
0117:            private transient static Current unique = null;
0118:
0119:            // private info	
0120:            private transient static TimerManager timermgr = null; // local
0121:            private transient static TransactionFactory tm = null; // local or remote
0122:            private transient static TransactionRecovery tr = null; // transaction recovery object
0123:
0124:            private static final String JOTM_VERSION = "JOTM 2.0.10";
0125:            private static final int DEFAULT_TIMEOUT = 60;
0126:            private int defaultTimeout = DEFAULT_TIMEOUT;
0127:            private int transactionTimeout = DEFAULT_TIMEOUT;
0128:            private static final boolean DEFAULT_RECOVERY = false;
0129:            private static boolean transactionRecovery = DEFAULT_RECOVERY;
0130:
0131:            // management counter
0132:            private transient int nb_bg_tx = 0;
0133:            private transient int nb_rb_tx = 0;
0134:            private transient int nb_cm_tx = 0;
0135:            private transient int nb_to = 0;
0136:
0137:            // ------------------------------------------------------------------
0138:            // Constructors
0139:            // ------------------------------------------------------------------
0140:
0141:            /**
0142:             * Default constructor.
0143:             * A client does not need the TMFactory.
0144:             */
0145:
0146:            public Current() {
0147:                TraceTm.jta.info(JOTM_VERSION);
0148:
0149:                if (TraceTm.jta.isDebugEnabled()) {
0150:                    TraceTm.jta.debug("no args constructor");
0151:                }
0152:
0153:                unique = this ;
0154:                timermgr = TimerManager.getInstance();
0155:
0156:                try {
0157:                    tr = new TransactionRecoveryImpl();
0158:                } catch (Exception e) {
0159:                    setDefaultRecovery(false);
0160:                    TraceTm.recovery.error("Cannot open Howl Log");
0161:                    TraceTm.recovery.error("JOTM Recovery is being disabled");
0162:                }
0163:            }
0164:
0165:            /**
0166:             * Constructor for an application server. 
0167:             * 
0168:             * The TM factory is passed as an argument. Note that the TM factory can be
0169:             * either local or remote.
0170:             * 
0171:             * @param tmfact TM Factory to use
0172:             */
0173:
0174:            public Current(TransactionFactory tmfact) {
0175:                TraceTm.jta.info(JOTM_VERSION);
0176:
0177:                if (TraceTm.jta.isDebugEnabled()) {
0178:                    TraceTm.jta.debug("TransactionFactory=" + tmfact);
0179:                }
0180:
0181:                unique = this ;
0182:                tm = tmfact;
0183:
0184:                timermgr = TimerManager.getInstance();
0185:
0186:                try {
0187:                    tr = new TransactionRecoveryImpl();
0188:                } catch (Exception e) {
0189:                    setDefaultRecovery(false);
0190:                    TraceTm.recovery.error("Cannot open Howl Log");
0191:                    TraceTm.recovery.error("JOTM Recovery is being disabled");
0192:                }
0193:            }
0194:
0195:            /**
0196:             * Gets the <code>TransactionManager</code> instance.
0197:             * 
0198:             * @return TransactionManager
0199:             */
0200:
0201:            public static TransactionManager getTransactionManager() {
0202:                return (TransactionManager) unique;
0203:            }
0204:
0205:            // ------------------------------------------------------------------
0206:            // UserTransaction implementation
0207:            // ------------------------------------------------------------------
0208:
0209:            /**
0210:             * Creates a new transaction and associate it with the current thread.
0211:             *
0212:             * @exception NotSupportedException Thrown if the thread is already
0213:             *    associated with a transaction. (nested transaction are not
0214:             *    supported)
0215:             *
0216:             * @exception SystemException Thrown if the transaction manager 
0217:             *    encounters an unexpected error condition
0218:             */
0219:
0220:            public void begin() throws NotSupportedException, SystemException {
0221:
0222:                if (TraceTm.jta.isDebugEnabled()) {
0223:                    TraceTm.jta.debug("begin transaction");
0224:                }
0225:
0226:                // checks that no transaction is already associated with this thread.
0227:                TransactionImpl tx = (TransactionImpl) threadTx.get();
0228:
0229:                if (TraceTm.jta.isDebugEnabled()) {
0230:                    TraceTm.jta.debug("threadTx.get= " + threadTx.toString());
0231:                }
0232:
0233:                if (tx != null) {
0234:                    if (txXids.containsValue(tx)) {
0235:                        throw new NotSupportedException(
0236:                                "Nested transactions not supported");
0237:                    } else {
0238:                        if (TraceTm.jta.isDebugEnabled()) {
0239:                            TraceTm.jta.debug("Resetting current tx = " + tx
0240:                                    + " since it is already completed.");
0241:                        }
0242:                    }
0243:                }
0244:
0245:                // builds a new Xid
0246:                // - should pass servername + ip addr. (LATER)
0247:                XidImpl otid = new XidImpl();
0248:
0249:                // creates a new TransactionImpl object
0250:                // - May raise SystemException
0251:                tx = new TransactionImpl(otid, transactionTimeout);
0252:
0253:                if (TraceTm.jta.isDebugEnabled()) {
0254:                    TraceTm.jta.debug("tx=" + tx);
0255:                }
0256:
0257:                /// clear suspended transaction. 
0258:                try {
0259:                    tx.doAttach(XAResource.TMJOIN);
0260:                } catch (RollbackException e) {
0261:                    // never.
0262:                    TraceTm.jotm.error("doAttach: RollbackException");
0263:                    throw new SystemException(
0264:                            "RollbackException in occured in begin() "
0265:                                    + e.getMessage());
0266:                }
0267:
0268:                // associates transaction with current thread
0269:                threadTx.set(tx);
0270:
0271:                if (TraceTm.jta.isDebugEnabled()) {
0272:                    TraceTm.jta.debug("threadTx.set= " + threadTx.toString());
0273:                }
0274:
0275:                // associates this Tx with the Xid
0276:                putTxXid(otid, tx);
0277:
0278:                // sets a timer for the transaction
0279:                if (timermgr != null) {
0280:                    tx.setTimer(timermgr.addTimer(tx, transactionTimeout, null,
0281:                            false));
0282:                }
0283:
0284:                // sets the time stamp for the transaction
0285:                Date myDate = new Date();
0286:                tx.setTxDate(myDate.toString());
0287:
0288:                // enlist all connections using the event callback this should be done in UserTransaction
0289:                // was done in doAttach
0290:                Stack curStack = (Stack) eventListStack.get();
0291:
0292:                if (curStack != null) { // if there is opened connections
0293:
0294:                    try {
0295:                        List list = (List) curStack.peek();
0296:
0297:                        if (list != null) {
0298:
0299:                            for (Iterator it = list.iterator(); it.hasNext();) {
0300:                                ((ResourceManagerEvent) it.next())
0301:                                        .enlistConnection(tx);
0302:                            }
0303:                        } else {
0304:
0305:                            if (TraceTm.jta.isDebugEnabled()) {
0306:                                TraceTm.jta
0307:                                        .debug("Current.begin called with null list");
0308:                            }
0309:                        }
0310:                    } catch (EmptyStackException e) {
0311:                        if (TraceTm.jta.isDebugEnabled()) {
0312:                            TraceTm.jta
0313:                                    .debug("Current.begin called with empty stack");
0314:                        }
0315:                    }
0316:                }
0317:            }
0318:
0319:            // ------------------------------------------------------------------
0320:            // Inflow Transaction implementation
0321:            // ------------------------------------------------------------------
0322:
0323:            /**
0324:             * Creates a new inflow transaction and associates it with the current thread.
0325:             *
0326:             * @param passxid <code>Xid</code> of the inflow transaction.
0327:             *
0328:             * @exception NotSupportedException Thrown if the thread is already
0329:             *    associated with a transaction. (nested transaction are not
0330:             *    supported)
0331:             *
0332:             * @exception SystemException Thrown if the transaction manager 
0333:             *    encounters an unexpected error condition
0334:             */
0335:
0336:            public void begin(javax.transaction.xa.Xid passxid)
0337:                    throws NotSupportedException, SystemException {
0338:                begin(passxid, (long) transactionTimeout);
0339:            }
0340:
0341:            /**
0342:             * Creates a new inflow transaction and associates it with the current thread.
0343:             *
0344:             * @param passxid <code>Xid</code> of the inflow transaction.
0345:             *
0346:             * @param timeout value of the timeout (in seconds). If the value is less than 
0347:             * or equal to zero, the value will be set to the default value.
0348:             *
0349:             * @exception NotSupportedException Thrown if the thread is already
0350:             *    associated with a transaction. (nested transaction are not
0351:             *    supported)
0352:             *
0353:             * @exception SystemException Thrown if the transaction manager 
0354:             *    encounters an unexpected error condition
0355:             */
0356:
0357:            public void begin(javax.transaction.xa.Xid passxid, long timeout)
0358:                    throws NotSupportedException, SystemException {
0359:
0360:                if (TraceTm.jta.isDebugEnabled()) {
0361:                    TraceTm.jta.debug("begin inflow transaction, timeout = "
0362:                            + timeout);
0363:                }
0364:
0365:                if (timeout <= 0) {
0366:                    timeout = defaultTimeout;
0367:                }
0368:
0369:                // checks that no transaction is already associated with this thread.
0370:                TransactionImpl tx = (TransactionImpl) threadTx.get();
0371:
0372:                if (TraceTm.jta.isDebugEnabled()) {
0373:                    TraceTm.jta.debug("threadTx.get= " + threadTx.toString());
0374:                }
0375:
0376:                if (tx != null) {
0377:                    if (txXids.containsValue(tx)) {
0378:                        throw new NotSupportedException(
0379:                                "Nested transactions not supported");
0380:                    } else {
0381:                        if (TraceTm.jta.isDebugEnabled()) {
0382:                            TraceTm.jta.debug("Resetting current tx = " + tx
0383:                                    + " since it is already completed.");
0384:                        }
0385:                    }
0386:                }
0387:
0388:                // stores the passed xid components
0389:                XidImpl pxid = new XidImpl(passxid);
0390:
0391:                // creates a new TransactionImpl object
0392:                // - May raise SystemException
0393:                tx = new TransactionImpl(pxid, (int) timeout);
0394:
0395:                if (TraceTm.jta.isDebugEnabled()) {
0396:                    TraceTm.jta.debug("tx=" + tx);
0397:                }
0398:
0399:                // associates transaction with current thread
0400:                threadTx.set(tx);
0401:
0402:                if (TraceTm.jta.isDebugEnabled()) {
0403:                    TraceTm.jta.debug("threadTx.set= " + threadTx.toString());
0404:                }
0405:
0406:                // associates this Tx with the Xid
0407:                putTxXid(pxid, tx);
0408:
0409:                // sets a timer for the transaction
0410:                if (timermgr != null) {
0411:                    tx.setTimer(timermgr.addTimer(tx, (int) timeout, null,
0412:                            false));
0413:                }
0414:
0415:                // sets the time stamp for the transaction
0416:                Date myDate = new Date();
0417:                tx.setTxDate(myDate.toString());
0418:            }
0419:
0420:            /**
0421:             * Gets the inflow transaction object that represents the transaction context of
0422:             * the calling thread.
0423:             *
0424:             * @return the XATerminator object representing the inflow transaction 
0425:             * associated with the calling thread. If the calling thread is
0426:             * not associated with an inflow transaction, a null object reference
0427:             * is returned.
0428:             *
0429:             * @exception XAException Thrown if the transaction manager 
0430:             * encounters an unexpected error condition
0431:             */
0432:
0433:            public XATerminator getXATerminator() throws XAException {
0434:
0435:                XATerminator xaterm = null;
0436:
0437:                try {
0438:                    xaterm = new XATerminatorImpl();
0439:                } catch (XAException e) {
0440:                    if (TraceTm.jta.isDebugEnabled()) {
0441:                        TraceTm.jta.debug("Cannot create XATerminatorImpl" + e);
0442:                    }
0443:                }
0444:
0445:                return xaterm;
0446:            }
0447:
0448:            // ------------------------------------------------------------------
0449:            // End of Inflow Transaction implementation
0450:            // ------------------------------------------------------------------
0451:
0452:            /**
0453:             * Commits the transaction associated with the current thread. When this
0454:             * method completes, the thread becomes associated with no transaction.
0455:             *
0456:             * @exception RollbackException Thrown to indicate that    the transaction
0457:             * has been rolled back rather than committed.
0458:             *
0459:             * @exception HeuristicMixedException Thrown to indicate that a heuristic
0460:             * decision was made and that some relevant updates have been committed
0461:             * while others have been rolled back.
0462:             *
0463:             * @exception HeuristicRollbackException Thrown to indicate that a
0464:             * heuristic decision was made and that some relevant updates have been
0465:             * rolled back.
0466:             *
0467:             * @exception SecurityException Thrown to indicate that the thread is not
0468:             * allowed to commit the transaction.
0469:             *
0470:             * @exception IllegalStateException Thrown if the current thread is    not
0471:             * associated with a transaction.
0472:             *
0473:             * @exception SystemException Thrown if the transaction manager encounters
0474:             * an unexpected error condition
0475:             */
0476:
0477:            public void commit() throws RollbackException,
0478:                    HeuristicMixedException, HeuristicRollbackException,
0479:                    SecurityException, IllegalStateException, SystemException {
0480:
0481:                if (TraceTm.jta.isDebugEnabled()) {
0482:                    TraceTm.jta.debug("commit transaction ");
0483:                }
0484:
0485:                // Get Transaction
0486:                TransactionImpl tx = (TransactionImpl) getTransaction();
0487:
0488:                if (tx == null) {
0489:                    throw new IllegalStateException(
0490:                            "Cannot get Transaction for commit");
0491:                }
0492:
0493:                if (TraceTm.jta.isDebugEnabled()) {
0494:                    TraceTm.jta.debug("tx=" + tx);
0495:                }
0496:
0497:                // Commit Transaction. Exceptions may be raised!
0498:                try {
0499:                    tx.commit();
0500:                } finally {
0501:                    // Dissociates the transaction from current thread
0502:                    // Has not been done in doDetach because we need to
0503:                    // be in the transactional context for beforeCompletion
0504:                    threadTx.set(null);
0505:
0506:                    // Reset the timeout to the default timeout
0507:                    transactionTimeout = defaultTimeout;
0508:
0509:                    if (TraceTm.jta.isDebugEnabled()) {
0510:                        TraceTm.jta.debug("threadTx.set= null");
0511:                        TraceTm.jta.debug("reset timeout= " + defaultTimeout);
0512:                    }
0513:                }
0514:            }
0515:
0516:            /**
0517:             * Rolls back the transaction associated with the current thread. When this
0518:             * method completes, the thread becomes associated with no transaction.
0519:             *
0520:             * @exception SecurityException Thrown to indicate that the thread is    not
0521:             * allowed to roll back the transaction.
0522:             *
0523:             * @exception IllegalStateException Thrown if the current thread is    not
0524:             * associated with a transaction.
0525:             *
0526:             * @exception SystemException Thrown if the transaction manager
0527:             * encounters an unexpected error condition
0528:             */
0529:            public void rollback() throws IllegalStateException,
0530:                    SecurityException, SystemException {
0531:
0532:                if (TraceTm.jta.isDebugEnabled()) {
0533:                    TraceTm.jta.debug("Current.rollback()");
0534:                }
0535:
0536:                // Get Transaction
0537:                TransactionImpl tx = (TransactionImpl) getTransaction();
0538:
0539:                if (tx == null) {
0540:                    throw new IllegalStateException(
0541:                            "Cannot get Transaction for rollback");
0542:                }
0543:
0544:                threadTx.set(null);
0545:
0546:                if (TraceTm.jta.isDebugEnabled()) {
0547:                    TraceTm.jta.debug("threadTx.set= null");
0548:                }
0549:
0550:                // Roll back the transaction. Exceptions may be raised!
0551:                tx.rollback();
0552:
0553:                if (TraceTm.jta.isDebugEnabled()) {
0554:                    TraceTm.jta.debug("reset timeout= " + defaultTimeout);
0555:                }
0556:
0557:                transactionTimeout = defaultTimeout;
0558:
0559:            }
0560:
0561:            /**
0562:             * Modify the transaction associated with the current thread such that the
0563:             * only possible outcome of the transaction is to roll back the transaction.
0564:             *
0565:             * @exception IllegalStateException Thrown if the current thread is    not
0566:             * associated with a transaction.
0567:             *
0568:             * @exception SystemException Thrown if the transaction manager
0569:             * encounters an unexpected error condition
0570:             */
0571:
0572:            public void setRollbackOnly() throws IllegalStateException,
0573:                    SystemException {
0574:
0575:                if (TraceTm.jta.isDebugEnabled()) {
0576:                    TraceTm.jta.debug("Current.setRollbackOnly()");
0577:                }
0578:                // Get Transaction
0579:                TransactionImpl tx = (TransactionImpl) getTransaction();
0580:
0581:                if (tx == null) {
0582:                    throw new IllegalStateException(
0583:                            "Cannot get Transaction for setRollbackOnly");
0584:                }
0585:
0586:                // Set transaction rollback only. Exceptions may be raised!
0587:                tx.setRollbackOnly();
0588:            }
0589:
0590:            /**
0591:             * Returns the status of the transaction associated with the current
0592:             * thread.
0593:             * 
0594:             * @return transaction status. If no transaction is associated with the
0595:             * current thread, this method returns the Status.NoTransaction value.
0596:             *
0597:             * @exception SystemException Thrown if the transaction manager
0598:             * encounters an unexpected error condition
0599:             */
0600:
0601:            public int getStatus() throws SystemException {
0602:
0603:                if (TraceTm.jta.isDebugEnabled()) {
0604:                    TraceTm.jta.debug("Current.getStatus()");
0605:                }
0606:
0607:                // Get Transaction
0608:                TransactionImpl tx = (TransactionImpl) getTransaction();
0609:
0610:                if (tx == null) {
0611:                    return Status.STATUS_NO_TRANSACTION;
0612:                }
0613:
0614:                // Get TX status. Exceptions may be raised!
0615:                return tx.getStatus();
0616:            }
0617:
0618:            /**
0619:             * Modifies the value of the timeout value that is associated with the
0620:             * transactions started by the current thread with the begin method.
0621:             *
0622:             *  If    an application has not called this method, the transaction
0623:             * service uses some default value for the transaction timeout.
0624:             *
0625:             * @param timeout value of the timeout (in seconds). If the value is zero,
0626:             * the transaction service restores the default value.
0627:             *
0628:             * @exception SystemException Thrown if the transaction manager
0629:             * encounters an unexpected error condition
0630:             */
0631:
0632:            public void setTransactionTimeout(int timeout)
0633:                    throws SystemException {
0634:
0635:                if (TraceTm.jta.isDebugEnabled()) {
0636:                    TraceTm.jta.debug("timeout= " + timeout);
0637:                }
0638:
0639:                // checks that no transaction is already associated with this thread.
0640:                // If one is, then we have a running transaction (ut.begin) and we must
0641:                // wait until transaction completes (ut.commit or ut.rollback)
0642:
0643:                TransactionImpl tx = (TransactionImpl) threadTx.get();
0644:
0645:                if (tx != null) {
0646:                    if (txXids.containsValue(tx)) {
0647:                        if (TraceTm.jta.isDebugEnabled()) {
0648:                            TraceTm.jta
0649:                                    .debug("Cannot reset transaction timeout, tx in execution");
0650:                        }
0651:                        // Cannot reset transaction timeout, tx (ut.begin)in execution, ignore.
0652:                        return;
0653:                    }
0654:                }
0655:
0656:                if (timeout > 0) {
0657:                    transactionTimeout = timeout;
0658:                } else {
0659:                    transactionTimeout = defaultTimeout;
0660:                }
0661:
0662:                if (TraceTm.jta.isDebugEnabled()) {
0663:                    TraceTm.jta.debug("Resetting transaction timeout= "
0664:                            + transactionTimeout);
0665:                }
0666:            }
0667:
0668:            /**
0669:             * Modifies the value of the recovery value that is associated with the
0670:             * transactions started by the current thread with the begin method.
0671:             *
0672:             * If an application has not called this method, the transaction
0673:             * service uses the default value of 'false' for recovery.
0674:             *
0675:             * @param recovery value of the recovery (true or faluse). If the value is
0676:             * false, recovery of transactions is disabled.
0677:             *
0678:             * @exception SystemException Thrown if the transaction manager
0679:             * encounters an unexpected error condition
0680:             */
0681:
0682:            public void setTransactionRecovery(boolean recovery)
0683:                    throws SystemException {
0684:
0685:                if (TraceTm.recovery.isDebugEnabled()) {
0686:                    TraceTm.recovery.debug("recovery=" + recovery);
0687:                }
0688:
0689:                if (recovery) {
0690:                    transactionRecovery = recovery;
0691:                } else {
0692:                    transactionRecovery = DEFAULT_RECOVERY;
0693:                }
0694:            }
0695:
0696:            // ------------------------------------------------------------------
0697:            // TransactionManager implementation
0698:            // (only the methods that are not already in UserTransaction)
0699:            // ------------------------------------------------------------------
0700:
0701:            /**
0702:             * Gets the transaction object that represents the transaction context of
0703:             * the calling thread.
0704:             *
0705:             * @return the Transaction object representing the transaction 
0706:             * associated with the calling thread. If the calling thread is
0707:             * not associated with a transaction, a null object reference
0708:             * is returned.
0709:             *
0710:             * @exception SystemException Thrown if the transaction manager 
0711:             * encounters an unexpected error condition
0712:             */
0713:
0714:            public Transaction getTransaction() throws SystemException {
0715:                Transaction ret = (Transaction) threadTx.get();
0716:
0717:                if (TraceTm.jta.isDebugEnabled()) {
0718:                    TraceTm.jta.debug("threadTx.get= " + threadTx.toString());
0719:                    TraceTm.jta.debug("Transaction ret= " + ret);
0720:                }
0721:
0722:                return ret;
0723:            }
0724:
0725:            /**
0726:             * Resumes the transaction context association of the calling thread with
0727:             * the transaction represented by the supplied Transaction object. When this
0728:             * method returns, the calling thread is associated with the transaction
0729:             * context specified. 
0730:             * <p><em>Warning</em>: No XA start is done here. We suppose it is already
0731:             * done after a <code>getConnection()</code>. 
0732:             * </p>
0733:             * The supposed programming model is: <ol>
0734:             * 	<li><code>getConnection()</code></li>
0735:             * 	<li>SQL code</li>
0736:             * 	<li><code>connection.close()</code</li>
0737:             * 	</ol>
0738:             *
0739:             * @param tobj The <code>Transaction</code> object that represents the
0740:             * transaction to be resumed.
0741:             *
0742:             * @exception InvalidTransactionException Thrown if the parameter
0743:             * transaction object contains an invalid transaction
0744:             *
0745:             * @exception IllegalStateException Thrown if the thread is already
0746:             * associated with another transaction.
0747:             *
0748:             * @exception SystemException Thrown if the transaction manager
0749:             * encounters an unexpected error condition
0750:             */
0751:
0752:            public void resume(Transaction tobj)
0753:                    throws InvalidTransactionException, IllegalStateException,
0754:                    SystemException {
0755:
0756:                if (TraceTm.jta.isDebugEnabled()) {
0757:                    TraceTm.jta.debug("resume transaction");
0758:                }
0759:
0760:                // invalid Transaction
0761:                if (tobj == null) {
0762:                    TraceTm.jotm.error("resume: null arg.");
0763:                    throw new InvalidTransactionException(
0764:                            "resume(null) is not valid");
0765:                }
0766:
0767:                if (TraceTm.jta.isDebugEnabled()) {
0768:                    TraceTm.jta.debug("tx=" + tobj);
0769:                }
0770:
0771:                // Checks that the thread is not already associated to ANOTHER transaction
0772:                Transaction mytx = (Transaction) threadTx.get();
0773:
0774:                if (TraceTm.jta.isDebugEnabled()) {
0775:                    TraceTm.jta.debug("threadTx.get= " + threadTx.toString());
0776:                }
0777:
0778:                if (mytx != null) {
0779:                    if (mytx.equals(tobj)) {
0780:                        if (TraceTm.jta.isDebugEnabled()) {
0781:                            TraceTm.jta.debug("nothing to do");
0782:                        }
0783:                        return;
0784:                    }
0785:                    TraceTm.jotm
0786:                            .error("resume: already associated with another transaction.");
0787:                    throw new IllegalStateException(
0788:                            "the thread is already associated with another transaction.");
0789:                }
0790:
0791:                // test for type before cast
0792:                if (!(tobj instanceof  TransactionImpl)) {
0793:                    TraceTm.jotm.error("resume: non TransactionImpl arg.");
0794:                    throw new InvalidTransactionException("resume("
0795:                            + tobj.getClass().getName() + ") is not valid");
0796:                }
0797:
0798:                // Associates this Tx with the current thread
0799:                threadTx.set(tobj);
0800:
0801:                if (TraceTm.jta.isDebugEnabled()) {
0802:                    TraceTm.jta.debug("threadTx.set= " + threadTx.toString());
0803:                }
0804:
0805:                // attach suspended resources
0806:                try {
0807:                    ((TransactionImpl) tobj).doAttach(XAResource.TMRESUME);
0808:                } catch (RollbackException e) {
0809:                    // never.
0810:                    TraceTm.jotm.error("RollbackException occured in resume()");
0811:                    throw new SystemException(
0812:                            "RollbackException in occured in resume() "
0813:                                    + e.getMessage());
0814:                }
0815:            }
0816:
0817:            /** 
0818:             * Suspends the transaction currently associated with the calling thread
0819:             * and return a <code>Transaction</code> object that represents the
0820:             * transaction context being suspended. 
0821:             * If the calling thread is not
0822:             * associated with a transaction, the method returns
0823:             * <code>null</code>. When this method returns, the calling thread is
0824:             * associated with no transaction.
0825:              <p><em>Warning</em>: No XA start is done here. We suppose it is already
0826:              done after a <code>getConnection()</code>.
0827:             * </p>
0828:             * The supposed programming model is: <ol>
0829:             * 	<li><code>getConnection()</code></li>
0830:             * 	<li>SQL code</li>
0831:             * 	<li><code>connection.close()</code</li>
0832:             * 	</ol>
0833:             * 
0834:             * @return Transaction object representing the suspended transaction.
0835:             *
0836:             * @exception SystemException Thrown if the transaction manager
0837:             * encounters an unexpected error condition
0838:             *
0839:             * @exception SystemException Thrown if the transaction manager
0840:             * encounters an unexpected error condition
0841:             */
0842:
0843:            public Transaction suspend() throws SystemException {
0844:
0845:                if (TraceTm.jta.isDebugEnabled()) {
0846:                    TraceTm.jta.debug("suspend transaction");
0847:                }
0848:
0849:                /// TMSUSPEND should be defined in Transaction.
0850:                TransactionImpl tx = (TransactionImpl) threadTx.get();
0851:
0852:                if (TraceTm.jta.isDebugEnabled()) {
0853:                    TraceTm.jta.debug("threadTx.get= " + threadTx.toString());
0854:                }
0855:
0856:                if (tx != null) {
0857:
0858:                    if (TraceTm.jta.isDebugEnabled()) {
0859:                        TraceTm.jta.debug("tx=" + tx);
0860:                    }
0861:
0862:                    tx.doDetach(XAResource.TMSUSPEND);
0863:                    threadTx.set(null);
0864:
0865:                    if (TraceTm.jta.isDebugEnabled()) {
0866:                        TraceTm.jta.debug("threadTx.set= null");
0867:                    }
0868:                }
0869:
0870:                return tx;
0871:            }
0872:
0873:            // ------------------------------------------------------------------
0874:            // ResourceManagerEventListener implementation
0875:            // Should be in UserTransaction only.
0876:            // ------------------------------------------------------------------
0877:
0878:            /** 
0879:             * @see org.objectweb.transaction.jta.ResourceManagerEventListener#connectionOpened(org.objectweb.transaction.jta.ResourceManagerEvent)
0880:             */
0881:
0882:            public void connectionOpened(ResourceManagerEvent event) {
0883:
0884:                if (TraceTm.jta.isDebugEnabled()) {
0885:                    TraceTm.jta.debug("Current.connectionOpened " + this );
0886:                }
0887:
0888:                List list = null;
0889:                Stack curStack = (Stack) eventListStack.get();
0890:                // get thread local stack
0891:
0892:                if (curStack == null) {
0893:                    // no stack yet : create one
0894:                    eventListStack.set(curStack = new Stack());
0895:                } else { // pop list from current stack
0896:                    try {
0897:                        list = (List) curStack.pop();
0898:                    } catch (EmptyStackException e) {
0899:                        // ignore: might happen if thread used by session bean
0900:                    }
0901:                }
0902:
0903:                // no list yet: create one
0904:                if (list == null)
0905:                    list = new Vector(1);
0906:
0907:                // add event to list
0908:                list.add(event);
0909:
0910:                if (TraceTm.jta.isDebugEnabled()) {
0911:                    TraceTm.jta.debug("list.add(event) = " + event);
0912:                }
0913:
0914:                // push list into stack
0915:                curStack.push(list);
0916:            }
0917:
0918:            /**
0919:             * @see org.objectweb.transaction.jta.ResourceManagerEventListener#connectionClosed(org.objectweb.transaction.jta.ResourceManagerEvent)
0920:             */
0921:
0922:            public void connectionClosed(ResourceManagerEvent event) {
0923:
0924:                if (TraceTm.jta.isDebugEnabled()) {
0925:                    TraceTm.jta.debug("Current.connectionClosed, remove");
0926:                }
0927:
0928:                // remove event from list
0929:                removeFromCurrentStack(event);
0930:            }
0931:
0932:            /**
0933:             * @see org.objectweb.transaction.jta.ResourceManagerEventListener#connectionErrorOccured(org.objectweb.transaction.jta.ResourceManagerEvent)
0934:             */
0935:
0936:            public void connectionErrorOccured(ResourceManagerEvent event) {
0937:
0938:                if (TraceTm.jta.isDebugEnabled()) {
0939:                    TraceTm.jta.debug("Current.connectionErrorOccured");
0940:                }
0941:
0942:                removeFromCurrentStack(event); // remove event from list
0943:            }
0944:
0945:            private void removeFromCurrentStack(ResourceManagerEvent event) {
0946:
0947:                if (TraceTm.jta.isDebugEnabled()) {
0948:                    TraceTm.jta
0949:                            .debug("Current.removeFromCurrentStack " + event);
0950:                    TraceTm.jta.debug("Current = " + this );
0951:                }
0952:
0953:                Stack curStack = (Stack) eventListStack.get();
0954:                // get thread local stack
0955:
0956:                if (curStack == null) {
0957:                    // if no transaction currently executing (no begin), no curStack
0958:                    // has been put on the eventListStack so just return
0959:                    return;
0960:                }
0961:
0962:                try {
0963:
0964:                    List list = (List) curStack.peek();
0965:
0966:                    if (list != null) {
0967:                        // get list from stack top
0968:
0969:                        list.remove(event);
0970:                    }
0971:                } catch (EmptyStackException e) {
0972:                    // no list of RM Events are known, just return
0973:                }
0974:            }
0975:
0976:            //
0977:            // objectweb transaction manager implementation
0978:            //
0979:
0980:            // thread local variable that stores all RM Events
0981:
0982:            private transient ThreadLocal eventListStack = new ThreadLocal();
0983:
0984:            /**
0985:             * @see org.objectweb.transaction.jta.TransactionManager#pushThreadLocalRMEventList(java.util.List)
0986:             */
0987:
0988:            public void pushThreadLocalRMEventList(List eventList) {
0989:
0990:                if (TraceTm.jta.isDebugEnabled()) {
0991:                    TraceTm.jta.debug("Current.pushThreadLocalRMEventList");
0992:                }
0993:
0994:                Stack curStack = (Stack) eventListStack.get();
0995:
0996:                if (curStack == null) {
0997:                    eventListStack.set(curStack = new Stack());
0998:                }
0999:
1000:                curStack.push(eventList);
1001:            }
1002:
1003:            /**
1004:             * @see org.objectweb.transaction.jta.TransactionManager#popThreadLocalRMEventList()
1005:             */
1006:
1007:            public List popThreadLocalRMEventList() {
1008:
1009:                if (TraceTm.jta.isDebugEnabled()) {
1010:                    TraceTm.jta.debug("Current.popThreadLocalRMEventList");
1011:                }
1012:
1013:                Stack curStack = (Stack) eventListStack.get();
1014:                return (List) curStack.pop();
1015:            }
1016:
1017:            // ------------------------------------------------------------------
1018:            // Referenceable implementation
1019:            // ------------------------------------------------------------------
1020:
1021:            /**
1022:             * Retrieves the <code>Reference</code> of this object. 
1023:             * 
1024:             * @return  The non-null <code>Reference</code> of this object.
1025:             *  
1026:             * @exception  NamingException  If a naming exception was encountered while retrieving the reference.  
1027:             */
1028:
1029:            public Reference getReference() throws NamingException {
1030:
1031:                if (TraceTm.jta.isDebugEnabled()) {
1032:                    TraceTm.jta.debug("Current.getReference()");
1033:                }
1034:
1035:                // create the reference
1036:                Reference ref = new Reference(this .getClass().getName(),
1037:                        "org.objectweb.jotm.UserTransactionFactory", null);
1038:                Integer i = new Integer(transactionTimeout);
1039:                ref.add(new StringRefAddr("jotm.timeout", i.toString()));
1040:                return ref;
1041:            }
1042:
1043:            // ------------------------------------------------------------------
1044:            // Other public methods
1045:            // ------------------------------------------------------------------
1046:
1047:            /**
1048:             * Returns the unique instance of the class or <code>null</code> if not
1049:             * initialized in case of plain client.
1050:             *
1051:             * @return The <code>Current</code> object created 
1052:             */
1053:
1054:            public static Current getCurrent() {
1055:
1056:                return unique;
1057:            }
1058:
1059:            /**
1060:             * Returns the TMFactory (in JTM)
1061:             * 
1062:             * @return TransactionFactory
1063:             */
1064:
1065:            public static TransactionFactory getJTM() {
1066:
1067:                if (tm == null) {
1068:                    TraceTm.jotm.error("Current: TMFactory is null!");
1069:                }
1070:
1071:                return tm;
1072:            }
1073:
1074:            /**
1075:             * Returns the Transaction Recovery object
1076:             * 
1077:             * @return TransactionRecovery
1078:             */
1079:
1080:            public static TransactionRecovery getTransactionRecovery() {
1081:
1082:                if (tr == null) {
1083:                    TraceTm.jotm
1084:                            .error("Current: Transaction Recovery is null!");
1085:                }
1086:
1087:                return tr;
1088:            }
1089:
1090:            /**
1091:             * Sets the default timeout value
1092:             * 
1093:             * @param timeout timeout value (in seconds)
1094:             */
1095:
1096:            public void setDefaultTimeout(int timeout) {
1097:
1098:                if (TraceTm.jta.isDebugEnabled()) {
1099:                    TraceTm.jta.debug("timeout= " + timeout);
1100:                }
1101:
1102:                if (timeout != 0) {
1103:                    defaultTimeout = timeout;
1104:                }
1105:
1106:                if (TraceTm.jta.isDebugEnabled()) {
1107:                    TraceTm.jta.debug("default timeout= " + defaultTimeout);
1108:                }
1109:
1110:            }
1111:
1112:            /**
1113:             * Gets the default timeout value
1114:             * 
1115:             * @return default timeout value (in seconds)
1116:             */
1117:
1118:            public int getDefaultTimeout() {
1119:
1120:                return defaultTimeout;
1121:            }
1122:
1123:            /**
1124:             * Sets the default recovery value
1125:             * 
1126:             * @param recovery recovery value (true or false)
1127:             */
1128:
1129:            public static void setDefaultRecovery(boolean recovery) {
1130:
1131:                TraceTm.recovery.info("Jotm Recovery= " + recovery);
1132:
1133:                transactionRecovery = recovery;
1134:            }
1135:
1136:            /**
1137:             * Gets the default recovery value
1138:             * 
1139:             * @return default recovery value (true or false)
1140:             */
1141:
1142:            public static boolean getDefaultRecovery() {
1143:
1144:                return transactionRecovery;
1145:            }
1146:
1147:            /**
1148:             * Associate to the current thread a transaction represented by its
1149:             * transaction context.
1150:             * This is used internally by the implicit propagation of the
1151:             * transactional context: 
1152:             * <ul>
1153:             * <li>in the skeleton, before calling the request (<code>isReply =
1154:             * 	false</code>)</li>
1155:             *  <li>in    the stub, after receiving the reply (<code>isReply =
1156:             * 	true</code>)</li>
1157:             * </ul>
1158:             * 
1159:             * @param pctx TransactionContext
1160:             * @param isReply <code>true</code> before calling a request,
1161:             * <code>false</code> after receiving a reply
1162:             */
1163:
1164:            public void setPropagationContext(TransactionContext pctx,
1165:                    boolean isReply) {
1166:
1167:                if (TraceTm.jotm.isDebugEnabled()) {
1168:                    TraceTm.jotm.debug("pctx=" + pctx + ", isReply=" + isReply);
1169:                }
1170:
1171:                if (pctx == null) { // never isReply when pctx=null
1172:
1173:                    if (TraceTm.jta.isDebugEnabled()) {
1174:                        TraceTm.jta.debug("detach tx");
1175:                    }
1176:
1177:                    TransactionImpl tx = (TransactionImpl) threadTx.get();
1178:
1179:                    if (TraceTm.jta.isDebugEnabled()) {
1180:                        TraceTm.jta.debug("threadTx.get= "
1181:                                + threadTx.toString());
1182:                    }
1183:
1184:                    if (tx != null) {
1185:                        // Free TransactionImpl, if not used only!!!
1186:                        // This is to avoid memory leaks.
1187:
1188:                        if (tx.isRemovable()) {
1189:                            forgetTx(tx.getXid());
1190:                        }
1191:
1192:                        // Detaches thread from any transaction
1193:                        threadTx.set(null);
1194:
1195:                        if (TraceTm.jta.isDebugEnabled()) {
1196:                            TraceTm.jta.debug("threadTx.set= null");
1197:                        }
1198:                    }
1199:
1200:                    return;
1201:                }
1202:
1203:                // Get the Transaction matching this Xid if it exists
1204:                Xid xid = pctx.getXid();
1205:                TransactionImpl tx = getTxXid(xid);
1206:
1207:                if (tx == null) {
1208:
1209:                    if (!isReply) { // create a Transaction object
1210:
1211:                        if (TraceTm.jta.isDebugEnabled()) {
1212:                            TraceTm.jta.debug("new Tx");
1213:                        }
1214:
1215:                        tx = new TransactionImpl(pctx);
1216:                        putTxXid(xid, tx);
1217:
1218:                        // sets the time stamp for the transaction
1219:                        Date myDate = new Date();
1220:                        tx.setTxDate(myDate.toString());
1221:
1222:                    } else {
1223:
1224:                        // This may happen with Jeremie and distributed transactions with
1225:                        // no dammage.
1226:
1227:                        if (TraceTm.jta.isDebugEnabled()) {
1228:                            TraceTm.jta.debug("unknown tx:" + xid);
1229:                        }
1230:                    }
1231:
1232:                } else {
1233:
1234:                    if (isReply) {
1235:                        // This thread is already associated to a transaction.
1236:                        // A proper PropagationContext exists yet, but it may have been changed
1237:                        // in case of distributed transaction.
1238:
1239:                        if (TraceTm.jta.isDebugEnabled()) {
1240:                            TraceTm.jta.debug("updating Xid=" + xid);
1241:                        }
1242:
1243:                        tx.updatePropagationContext(pctx);
1244:                    } else {
1245:
1246:                        if (TraceTm.jta.isDebugEnabled()) {
1247:                            TraceTm.jta.debug("transaction already known:"
1248:                                    + xid);
1249:                        }
1250:                    }
1251:                }
1252:
1253:                // Associates this Tx with the current thread (= resume)
1254:                // In case of Jeremy, if isReply, we are not in the correct thread, so
1255:                // never touch threadTx in that case!!!
1256:
1257:                if (!isReply) {
1258:                    threadTx.set(tx);
1259:
1260:                    if (TraceTm.jta.isDebugEnabled()) {
1261:                        TraceTm.jta.debug("threadTx.set= "
1262:                                + threadTx.toString());
1263:                    }
1264:                }
1265:            }
1266:
1267:            /**
1268:             * Get the transaction context associated with the current thread or null
1269:             * if the thread is not involved in a transaction.
1270:             */
1271:
1272:            public TransactionContext getPropagationContext(boolean hold) {
1273:
1274:                if (TraceTm.jotm.isDebugEnabled()) {
1275:                    TraceTm.jotm.debug("hold=" + hold);
1276:                }
1277:
1278:                try {
1279:                    TransactionImpl tx = (TransactionImpl) getTransaction();
1280:
1281:                    if (tx != null) { // will return null if Tx not valid.
1282:                        return tx.getPropagationContext(hold);
1283:                    }
1284:                } catch (SystemException e) {
1285:                    TraceTm.jotm.error(
1286:                            "getPropagationContext system exception:", e);
1287:                }
1288:
1289:                return null;
1290:            }
1291:
1292:            /**
1293:             * Forget all about this transaction.
1294:             * References to <code>TransactionImpl</code> must be destroyed to allow
1295:             * the garbage collector to free memory allocated to this transaction.
1296:             * 
1297:             * @param xid <code>Xid</code> of the transaction
1298:             */
1299:
1300:            public void forgetTx(Xid xid) {
1301:
1302:                // Only clear threadTx if this thread is working on its Xid
1303:
1304:                TransactionImpl txCur = (TransactionImpl) txXids.get(xid);
1305:
1306:                if (txCur != null
1307:                        && txCur.equals((TransactionImpl) threadTx.get())) {
1308:                    threadTx.set(null);
1309:
1310:                    if (TraceTm.jta.isDebugEnabled()) {
1311:                        TraceTm.jta.debug("threadTx.set = null");
1312:                    }
1313:                }
1314:                removeTxXid(xid);
1315:            }
1316:
1317:            /**
1318:             * Get the transaction referenced by Xid.
1319:             * 
1320:             * @param xid <code>Xid</code> of the transaction
1321:             */
1322:
1323:            public TransactionImpl getTxByXid(Xid xid) {
1324:
1325:                TransactionImpl tx = (TransactionImpl) txXids.get(xid);
1326:                return tx;
1327:            }
1328:
1329:            /**
1330:             * Get the Xid's of all prepared transactions.
1331:             * 
1332:             * @return array of all Xids in the prepared state
1333:             */
1334:
1335:            public javax.transaction.xa.Xid[] getPreparedHeuristicXid() {
1336:
1337:                Vector xidlist;
1338:                int xidcount;
1339:                javax.transaction.xa.Xid xid = null;
1340:
1341:                xidcount = txXids.size(); /* Xid count */
1342:
1343:                if (xidcount == 0) {
1344:                    return null;
1345:                }
1346:
1347:                xidlist = new Vector();
1348:
1349:                Set txXidsSet = txXids.keySet();
1350:
1351:                synchronized (txXids) {
1352:
1353:                    Iterator txXidsIterator = txXidsSet.iterator();
1354:
1355:                    while (txXidsIterator.hasNext()) {
1356:                        TransactionImpl tx = (TransactionImpl) txXids
1357:                                .get(txXidsIterator.next());
1358:
1359:                        try {
1360:
1361:                            if (tx.getStatus() == Status.STATUS_PREPARED) {
1362:                                xid = (javax.transaction.xa.Xid) tx.getXid();
1363:                                xidlist.add(xid);
1364:                            }
1365:                        } catch (SystemException e) {
1366:                            TraceTm.jotm
1367:                                    .error(
1368:                                            "getPreparedHeuristicsXid system exception:",
1369:                                            e);
1370:                        }
1371:                    }
1372:                }
1373:
1374:                Vector mytxrecovered = JotmRecovery.getTxRecovered();
1375:
1376:                return (javax.transaction.xa.Xid[]) xidlist.toArray();
1377:            }
1378:
1379:            /**
1380:             * Get all Xid's associated with this transaction.
1381:             * 
1382:             * @return array of all Xids
1383:             */
1384:
1385:            public javax.transaction.xa.Xid[] getAllXid() {
1386:
1387:                Vector xidlist;
1388:                int xidcount;
1389:                javax.transaction.xa.Xid xid = null;
1390:
1391:                xidcount = txXids.size(); /* Xid count */
1392:
1393:                if (xidcount == 0) {
1394:                    return null;
1395:                }
1396:
1397:                xidlist = new Vector();
1398:
1399:                Set txXidsSet = txXids.keySet();
1400:
1401:                synchronized (txXids) {
1402:
1403:                    Iterator txXidsIterator = txXidsSet.iterator();
1404:
1405:                    while (txXidsIterator.hasNext()) {
1406:                        TransactionImpl mytx = (TransactionImpl) txXids
1407:                                .get(txXidsIterator.next());
1408:                        xid = (javax.transaction.xa.Xid) mytx.getXid();
1409:                        xidlist.add(xid);
1410:                    }
1411:                }
1412:
1413:                return (javax.transaction.xa.Xid[]) xidlist.toArray();
1414:            }
1415:
1416:            /**
1417:             * Get all executing transactions.
1418:             * 
1419:             * @return array of all Transactions in execution
1420:             */
1421:
1422:            public String[] getAllTx() {
1423:
1424:                Vector txList;
1425:                List txResourceList;
1426:                int txCount;
1427:                int txResourceCount;
1428:                String txStatusName;
1429:
1430:                txCount = txXids.size(); /* transaction count */
1431:
1432:                if (txCount == 0) {
1433:                    return null;
1434:                }
1435:
1436:                txList = new Vector();
1437:
1438:                Set txXidsSet = txXids.keySet();
1439:
1440:                synchronized (txXids) {
1441:
1442:                    Iterator txXidsIterator = txXidsSet.iterator();
1443:
1444:                    while (txXidsIterator.hasNext()) {
1445:                        TransactionImpl mytx = (TransactionImpl) txXids
1446:                                .get(txXidsIterator.next());
1447:
1448:                        try {
1449:                            txStatusName = StatusHelper.getStatusName(mytx
1450:                                    .getStatus());
1451:                        } catch (SystemException e) {
1452:                            txStatusName = "No State Defined";
1453:                        }
1454:
1455:                        txResourceList = mytx.getEnlistedXAResource();
1456:                        txResourceCount = txResourceList.size();
1457:
1458:                        if (txResourceCount == 0) {
1459:                            txList.add(mytx.getTxDate() + "????"
1460:                                    + mytx.toString() + "????"
1461:                                    + "NO Resource Defined" + "????"
1462:                                    + txStatusName);
1463:                        } else {
1464:
1465:                            for (int i = 0; i < txResourceCount; i++) {
1466:                                txList.add(mytx.getTxDate() + "????"
1467:                                        + mytx.toString() + "????"
1468:                                        + txResourceList.get(i).toString()
1469:                                        + "????" + txStatusName);
1470:                            }
1471:                        }
1472:                    }
1473:                }
1474:
1475:                String[] myTxString = new String[txCount];
1476:
1477:                for (int i = 0; i < txCount; i++) {
1478:                    myTxString[i] = txList.get(i).toString();
1479:                }
1480:
1481:                return myTxString;
1482:            }
1483:
1484:            /**
1485:             * Get all Transactions that may require recovery.
1486:             * 
1487:             * @return array of all Transactions that may require recovery
1488:             */
1489:
1490:            public String[] getAllRcTx() {
1491:
1492:                Vector vTxRecovered = null;
1493:                Vector txList;
1494:                int txCount;
1495:
1496:                JotmRecovery myjr = null;
1497:
1498:                if (tr == null) {
1499:                    if (TraceTm.recovery.isDebugEnabled()) {
1500:                        TraceTm.recovery.debug("tr= null");
1501:                    }
1502:                    return null;
1503:                }
1504:
1505:                myjr = tr.getJotmRecovery();
1506:
1507:                if (myjr == null) {
1508:                    return null;
1509:                }
1510:
1511:                vTxRecovered = JotmRecovery.getTxRecovered();
1512:
1513:                txCount = vTxRecovered.size();
1514:
1515:                if (TraceTm.recovery.isDebugEnabled()) {
1516:                    TraceTm.recovery.debug("txcount= " + txCount);
1517:                }
1518:
1519:                if (txCount == 0) {
1520:                    return null;
1521:                }
1522:
1523:                txList = new Vector();
1524:                TxRecovered mytxRecovered = null;
1525:
1526:                for (int i = 0; i < txCount; i++) {
1527:                    mytxRecovered = (TxRecovered) vTxRecovered.elementAt(i);
1528:
1529:                    Xid temptxxid = new XidImpl(mytxRecovered.gettxxid());
1530:
1531:                    // We must send the complete transaction Xid string along
1532:                    // with the truncated. The complete will be used for further
1533:                    // searching while the truncated will be used in the display
1534:                    // of the JSP.
1535:
1536:                    txList.add(new String(mytxRecovered.gettxxid()) + "????"
1537:                            + temptxxid.toString() + "????"
1538:                            + mytxRecovered.gettxdatetime() + "????"
1539:                            + mytxRecovered.getxidcount());
1540:                }
1541:
1542:                String[] myTxString = new String[txCount];
1543:
1544:                for (int i = 0; i < txCount; i++) {
1545:                    myTxString[i] = txList.get(i).toString();
1546:                }
1547:
1548:                return myTxString;
1549:            }
1550:
1551:            /**
1552:             * Get all XAResources that may require recovery.
1553:             * 
1554:             * @return array of all XAResources that may require recovery
1555:             */
1556:
1557:            public String[] getAllXaTx(String stx) {
1558:
1559:                Vector xaList;
1560:                Vector rmList;
1561:                int txCount;
1562:                int rmiCount;
1563:                int myxacount = 0;
1564:                boolean mytxfound = false;
1565:                boolean myrmifound = false;
1566:                boolean myrmregistered = false;
1567:                boolean myxaresfound = false;
1568:                String mytxstatusname;
1569:
1570:                JotmRecovery myjr = null;
1571:
1572:                if (tr == null) {
1573:                    return null;
1574:                }
1575:
1576:                myjr = tr.getJotmRecovery();
1577:
1578:                if (myjr == null) {
1579:                    if (TraceTm.recovery.isDebugEnabled()) {
1580:                        TraceTm.recovery.debug("myjr= null");
1581:                    }
1582:                    return null;
1583:                }
1584:
1585:                xaList = new Vector();
1586:                TxxidRecovered mytxxidRecovered = null;
1587:                TxRecovered mytxRecovered = null;
1588:                Vector vTxRecovered = null;
1589:                Vector vRecoverRmInfo = null;
1590:                RmRegistration myRmRegistration = null;
1591:                String myxares = null;
1592:
1593:                vTxRecovered = JotmRecovery.getTxRecovered();
1594:
1595:                txCount = vTxRecovered.size();
1596:
1597:                if (TraceTm.recovery.isDebugEnabled()) {
1598:                    TraceTm.recovery.debug("txcount= " + txCount);
1599:                }
1600:
1601:                for (int i = 0; i < txCount; i++) {
1602:                    mytxRecovered = (TxRecovered) vTxRecovered.elementAt(i);
1603:
1604:                    if (TraceTm.recovery.isDebugEnabled()) {
1605:                        TraceTm.recovery.debug("gettxxid= "
1606:                                + new String(mytxRecovered.gettxxid()));
1607:                        TraceTm.recovery.debug("stx=" + stx);
1608:                    }
1609:
1610:                    if (new String(mytxRecovered.gettxxid()).equals(stx)) {
1611:                        mytxfound = true;
1612:                        break;
1613:                    }
1614:                }
1615:
1616:                rmList = new Vector();
1617:                RecoverRmInfo rmInfo = null;
1618:                vRecoverRmInfo = JotmRecovery.getRecoverRmInfo();
1619:                String myrm = null;
1620:                Vector vRmRegistration = tr.getRmRegistration();
1621:
1622:                if (mytxfound) {
1623:                    myxacount = mytxRecovered.getxidcount();
1624:
1625:                    if (TraceTm.recovery.isDebugEnabled()) {
1626:                        TraceTm.recovery.debug("myxacount= " + myxacount);
1627:                    }
1628:
1629:                    for (int i = 0; i < myxacount; i++) {
1630:                        myrmregistered = false;
1631:                        myrmifound = false;
1632:                        myxaresfound = false;
1633:                        mytxxidRecovered = mytxRecovered.getRecoverTxXidInfo(i);
1634:
1635:                        if (mytxxidRecovered == null) {
1636:                            xaList.add("NotFound" + "????" + "NotFound"
1637:                                    + "????" + "NotFound" + "????" + "NotFound"
1638:                                    + "????" + "NotFound");
1639:                        } else {
1640:                            rmiCount = vRecoverRmInfo.size();
1641:
1642:                            if (TraceTm.recovery.isDebugEnabled()) {
1643:                                TraceTm.recovery.debug("rmiCount= " + rmiCount);
1644:                            }
1645:
1646:                            for (int j = 0; j < rmiCount; j++) {
1647:                                rmInfo = (RecoverRmInfo) vRecoverRmInfo
1648:                                        .elementAt(j);
1649:
1650:                                if (TraceTm.recovery.isDebugEnabled()) {
1651:                                    TraceTm.recovery
1652:                                            .debug("getRecoverXaResName()= "
1653:                                                    + rmInfo
1654:                                                            .getRecoverXaResName());
1655:                                    TraceTm.recovery
1656:                                            .debug("getRecoverxaresname()="
1657:                                                    + mytxxidRecovered
1658:                                                            .getRecoverxaresname());
1659:                                    TraceTm.recovery
1660:                                            .debug("getRecoverXaRes()= "
1661:                                                    + new String(rmInfo
1662:                                                            .getRecoverXaRes()));
1663:                                    TraceTm.recovery.debug("getRecoverxares()="
1664:                                            + new String(mytxxidRecovered
1665:                                                    .getRecoverxares()));
1666:                                }
1667:
1668:                                // if (rmInfo.getRecoverXaResName().equals(mytxxidRecovered.getRecoverxaresname())) {
1669:                                if ((new String(rmInfo.getRecoverXaRes()))
1670:                                        .equals(new String(mytxxidRecovered
1671:                                                .getRecoverxares()))) {
1672:                                    myrm = rmInfo.getRecoverRm();
1673:                                    myrmifound = true;
1674:                                    myxares = new String(mytxxidRecovered
1675:                                            .getRecoverxares());
1676:
1677:                                    if (TraceTm.recovery.isDebugEnabled()) {
1678:                                        TraceTm.recovery.debug("myrm= " + myrm);
1679:                                        TraceTm.recovery.debug("myxares= "
1680:                                                + myxares);
1681:                                    }
1682:                                    break;
1683:                                }
1684:                            }
1685:
1686:                            if (!myrmifound) {
1687:                                myrm = "NotFound";
1688:                            }
1689:
1690:                            if (vRmRegistration == null) {
1691:                                if (TraceTm.recovery.isDebugEnabled()) {
1692:                                    TraceTm.recovery
1693:                                            .debug("vRmRegistration is null");
1694:                                }
1695:                                myxares = "NotRegistered";
1696:                            } else {
1697:                                int rmregcount = vRmRegistration.size();
1698:
1699:                                if (TraceTm.recovery.isDebugEnabled()) {
1700:                                    TraceTm.recovery.debug("rmregcount= "
1701:                                            + rmregcount);
1702:                                }
1703:
1704:                                for (int j = 0; j < rmregcount; j++) {
1705:                                    myRmRegistration = (RmRegistration) vRmRegistration
1706:                                            .elementAt(j);
1707:
1708:                                    if (TraceTm.recovery.isDebugEnabled()) {
1709:                                        TraceTm.recovery.debug("myrm= " + myrm);
1710:                                        TraceTm.recovery.debug("rmGetName= "
1711:                                                + myRmRegistration.rmGetName());
1712:                                    }
1713:
1714:                                    if (myrm.equals(myRmRegistration
1715:                                            .rmGetName())) {
1716:                                        myrmregistered = true;
1717:
1718:                                        if (myRmRegistration.rmGetXaRes() == null) {
1719:                                            myxares = "IsNull";
1720:                                        } else {
1721:                                            myxares = myRmRegistration
1722:                                                    .rmGetXaRes().toString();
1723:                                            myxaresfound = true;
1724:
1725:                                            if (TraceTm.recovery
1726:                                                    .isDebugEnabled()) {
1727:                                                TraceTm.recovery
1728:                                                        .debug("myxares= "
1729:                                                                + myxares);
1730:                                            }
1731:                                        }
1732:                                        break;
1733:                                    }
1734:                                }
1735:
1736:                                if (!myrmregistered) {
1737:                                    myxares = "NotRegistered";
1738:                                }
1739:
1740:                                if (TraceTm.recovery.isDebugEnabled()) {
1741:                                    TraceTm.recovery.debug("myxares= "
1742:                                            + myxares);
1743:                                }
1744:                            }
1745:
1746:                            Xid tempxid = new XidImpl(mytxxidRecovered
1747:                                    .getRecoverxid());
1748:
1749:                            // We must send the complete Xid string along with the truncated.
1750:                            // The complete will be used for further searching while the
1751:                            // truncated will be used in the display of the JSP.
1752:                            xaList.add(myrm
1753:                                    + "????"
1754:                                    + myxares
1755:                                    + "????"
1756:                                    + new String(mytxxidRecovered
1757:                                            .getRecoverxid())
1758:                                    + "????"
1759:                                    + new String(tempxid.toString())
1760:                                    + "????"
1761:                                    + StatusHelper
1762:                                            .getStatusName(mytxxidRecovered
1763:                                                    .getRecoverstatus()));
1764:                        }
1765:                    }
1766:                }
1767:
1768:                String[] myTxString = new String[myxacount];
1769:
1770:                for (int i = 0; i < myxacount; i++) {
1771:                    myTxString[i] = xaList.get(i).toString();
1772:                }
1773:
1774:                return myTxString;
1775:            }
1776:
1777:            /**
1778:             * @return Returns all XAResources that require administrator recovery action.
1779:             */
1780:            public int actionXAResource(String xaAction, String xatx) {
1781:                int commiterror;
1782:
1783:                Vector vRmRegistration = null;
1784:                Vector vRecoverRmInfo = null;
1785:                int rmregcount;
1786:                boolean mytxfound = false;
1787:                boolean myrmifound = false;
1788:                String mytxstatusname;
1789:                JotmRecovery myjr = null;
1790:                RmRegistration myRmRegistration = null;
1791:                XAResource xaresource = null;
1792:
1793:                if (tr == null) {
1794:                    return 0;
1795:                }
1796:
1797:                myjr = tr.getJotmRecovery();
1798:
1799:                if (myjr == null) {
1800:                    return 0;
1801:                }
1802:
1803:                vRmRegistration = tr.getRmRegistration();
1804:
1805:                if (vRmRegistration == null) {
1806:                    return 0;
1807:                }
1808:
1809:                // Given the passed Resource Manager, find it in the RMRegistered vector.
1810:                // When the Resource Manager is found, use the XAResource associated with
1811:                // the RMRegistered Resource Manager to perform a XAResource.recover call
1812:                // to return all XIDs that require recovery.
1813:                // With the list of XIDs to be recovered, verify that the Xid passes in
1814:                // the list. If the Xid passed is in the recover list, then we can attempt
1815:                // the commit of the Xid (i.e., XAResource.Commit(Xid)).
1816:                // When the commit is completed, we can remove the TxXidRecovered array
1817:                // entry associated with the Xid and decrement the count in its respective
1818:                // TxRecovered vector entry. If the count in the TxRecovered vector entry
1819:                // is zero, we can then remove the TxRecovered entry from the vector.
1820:
1821:                String mys = xatx;
1822:                int myix1 = mys.indexOf('\n');
1823:                String sResmgr = mys.substring(0, myix1);
1824:                int myix2 = mys.indexOf('\n', myix1 + 1);
1825:                String sResource = mys.substring(myix1 + 1, myix2);
1826:                int myix3 = mys.indexOf('\n', myix2 + 1);
1827:                String sFullXid = mys.substring(myix2 + 1, myix3);
1828:                String sXidstate = mys.substring(myix3 + 1);
1829:
1830:                rmregcount = vRmRegistration.size();
1831:
1832:                for (int i = 0; i < rmregcount; i++) {
1833:                    myRmRegistration = (RmRegistration) vRmRegistration
1834:                            .elementAt(i);
1835:
1836:                    if (sResmgr.equals(myRmRegistration.rmGetName())) {
1837:                        xaresource = myRmRegistration.rmGetXaRes();
1838:                        break;
1839:                    }
1840:                }
1841:
1842:                int rcflag = 0;
1843:
1844:                javax.transaction.xa.Xid javaxid[] = new javax.transaction.xa.Xid[100];
1845:
1846:                try {
1847:                    // recover returns javax.transaction.xa.Xid objects
1848:                    // we must cast to org.objectweb.jotm.Xid objects
1849:                    javaxid = xaresource.recover(rcflag);
1850:                } catch (XAException e) {
1851:                    if (TraceTm.jta.isDebugEnabled()) {
1852:                        TraceTm.recovery
1853:                                .debug("xaResource.recover call failed during recovery "
1854:                                        + e.getMessage());
1855:                    }
1856:                }
1857:
1858:                if (javaxid == null) {
1859:
1860:                    if (TraceTm.recovery.isDebugEnabled()) {
1861:                        TraceTm.recovery
1862:                                .debug("No XIDs to recover for Xares javaxid is null");
1863:                    }
1864:
1865:                    cleanuptxrecovery(sFullXid);
1866:                    return 0;
1867:                }
1868:
1869:                if (javaxid.length == 0) {
1870:
1871:                    if (TraceTm.recovery.isDebugEnabled()) {
1872:                        TraceTm.recovery.debug("No XIDs to recover for Xares= "
1873:                                + xaresource);
1874:                    }
1875:
1876:                    cleanuptxrecovery(sFullXid);
1877:                    return 0;
1878:                }
1879:
1880:                Xid rcxid[] = new Xid[javaxid.length];
1881:
1882:                for (int xx = 0; xx < javaxid.length; xx++) {
1883:
1884:                    if (javaxid[xx] == null)
1885:                        break;
1886:
1887:                    if (new String(javaxid[xx].toString()).equals(sFullXid)) {
1888:
1889:                        if (xaAction == "commit") {
1890:                            try {
1891:                                xaresource.commit(javaxid[xx], false);
1892:                            } catch (XAException e) {
1893:                                TraceTm.recovery
1894:                                        .error("Unable to commit Xid during Admin Recovery "
1895:                                                + e.getMessage());
1896:                            }
1897:                        } else {
1898:                            if (xaAction == "rollback") {
1899:                                try {
1900:                                    xaresource.rollback(javaxid[xx]);
1901:                                } catch (XAException e) {
1902:                                    TraceTm.recovery
1903:                                            .error("Unable to rollback Xid during Admin Recovery "
1904:                                                    + e.getMessage());
1905:                                }
1906:                            } else {
1907:                                if (xaAction == "forget") {
1908:                                    try {
1909:                                        xaresource.rollback(javaxid[xx]);
1910:                                    } catch (XAException e) {
1911:                                        TraceTm.recovery
1912:                                                .error("Unable to rollback Xid during Admin Recovery "
1913:                                                        + e.getMessage());
1914:                                    }
1915:                                }
1916:                            }
1917:                        }
1918:                    }
1919:                    break;
1920:                }
1921:
1922:                cleanuptxrecovery(sFullXid);
1923:                return 0;
1924:            }
1925:
1926:            private void cleanuptxrecovery(String pFullXid) {
1927:
1928:                // We can now remove the TxXidRecovered array entry associated with the
1929:                // Xid and decrement the count in its respective TxRecovered vector entry.
1930:                // If the count in the TxRecovered vector entry is zero, we can then remove
1931:                // the TxRecovered entry from the vector.
1932:
1933:                Vector vTxRecovered = null;
1934:                TxRecovered mytxRecovered = null;
1935:                TxxidRecovered mytxxidRecovered = null;
1936:                int txCount;
1937:                int myxacount = 0;
1938:                boolean mytxxidrecoveredfound = false;
1939:
1940:                byte[] jotmDone = new byte[11];
1941:                byte[][] jotmDoneRecord = new byte[1][11];
1942:
1943:                jotmDone = "RR3JOTMDONE".getBytes();
1944:
1945:                vTxRecovered = JotmRecovery.getTxRecovered();
1946:                txCount = vTxRecovered.size();
1947:
1948:                for (int i = 0; i < txCount; i++) {
1949:                    mytxRecovered = (TxRecovered) vTxRecovered.elementAt(i);
1950:                    myxacount = mytxRecovered.getxidcount();
1951:
1952:                    for (int j = 0; j < myxacount; j++) {
1953:                        mytxxidRecovered = mytxRecovered.getRecoverTxXidInfo(j);
1954:
1955:                        if (mytxxidRecovered != null) {
1956:
1957:                            if (pFullXid.equals(new String(mytxxidRecovered
1958:                                    .getRecoverxid()))) {
1959:                                // mytxxidRecovered.setRecoverstatus(Status.STATUS_NO_TRANSACTION);
1960:                                mytxxidRecovered
1961:                                        .setRecoverstatus(Status.STATUS_COMMITTED);
1962:                                mytxxidrecoveredfound = true;
1963:                                break;
1964:                            }
1965:                        }
1966:                    }
1967:
1968:                    boolean allcompleted = true;
1969:
1970:                    for (int j = 0; j < myxacount; j++) {
1971:                        mytxxidRecovered = mytxRecovered.getRecoverTxXidInfo(j);
1972:
1973:                        // if (mytxxidRecovered.getRecoverstatus() != Status.STATUS_NO_TRANSACTION) {  // something other than completed
1974:                        if (mytxxidRecovered.getRecoverstatus() != Status.STATUS_COMMITTED) { // something other than completed
1975:                            allcompleted = false;
1976:                            break;
1977:                        }
1978:                    }
1979:
1980:                    if (allcompleted) {
1981:                        XACommittingTx xaCommitTx = mytxRecovered
1982:                                .getXACommittingTx();
1983:                        jotmDoneRecord[0] = jotmDone;
1984:
1985:                        if (Current.getDefaultRecovery()) {
1986:                            try {
1987:                                if (TraceTm.recovery.isDebugEnabled()) {
1988:                                    TraceTm.recovery
1989:                                            .debug("Done howl log, after admin action");
1990:                                }
1991:
1992:                                TransactionRecoveryImpl
1993:                                        .getTransactionRecovery().howlDoneLog(
1994:                                                jotmDoneRecord, xaCommitTx);
1995:                            } catch (Exception f) {
1996:                                String howlerror = "Cannot howlDoneLog:" + f
1997:                                        + "--" + f.getMessage();
1998:                                TraceTm.jotm
1999:                                        .error("Got LogException from howlDoneLog: "
2000:                                                + howlerror);
2001:                            }
2002:                        }
2003:
2004:                        vTxRecovered.remove(i);
2005:                        break;
2006:                    }
2007:
2008:                    if (mytxxidrecoveredfound)
2009:                        return;
2010:                }
2011:            }
2012:
2013:            /**
2014:             * Associate Thread to this transaction.
2015:             * (used by iiop interceptor)
2016:             */
2017:
2018:            public void associateThreadTx(Xid xid) {
2019:
2020:                TransactionImpl tx = getTxXid(xid);
2021:                threadTx.set(tx);
2022:
2023:                if (TraceTm.jta.isDebugEnabled()) {
2024:                    TraceTm.jta.debug("threadTx.set= " + threadTx.toString());
2025:                }
2026:            }
2027:
2028:            /**
2029:             * Clear transaction from this thread if not known.
2030:             * Useful when another thread completes the current thread's transaction
2031:             */
2032:            public void clearThreadTx() {
2033:
2034:                TransactionImpl tx = (TransactionImpl) threadTx.get();
2035:
2036:                if (tx != null) {
2037:                    threadTx.set(null);
2038:                    if (TraceTm.jta.isDebugEnabled()) {
2039:                        TraceTm.jta.debug("threadTx.set=null");
2040:                    }
2041:                }
2042:            }
2043:
2044:            // ------------------------------------------------------------------
2045:            // private methods
2046:            // ------------------------------------------------------------------
2047:
2048:            /*
2049:             * put the Tx/Xid mapping into the hashtable.
2050:             */
2051:
2052:            private void putTxXid(Xid xid, TransactionImpl tx) {
2053:
2054:                if (TraceTm.jta.isDebugEnabled()) {
2055:                    TraceTm.jta.debug("Associate tx to xid (xid=" + xid + ")");
2056:                }
2057:
2058:                txXids.put(xid, tx);
2059:            }
2060:
2061:            /*
2062:             * given the Xid, get the corresponding Tx from the hashtable.
2063:             */
2064:
2065:            private TransactionImpl getTxXid(Xid xid) {
2066:
2067:                if (TraceTm.jta.isDebugEnabled()) {
2068:                    TraceTm.jta.debug("get tx from xid (xid=" + xid + ")");
2069:                }
2070:
2071:                TransactionImpl tx = (TransactionImpl) txXids.get(xid);
2072:                return tx;
2073:            }
2074:
2075:            /*
2076:             * removeTxXid method.
2077:             */
2078:
2079:            private void removeTxXid(Xid xid) {
2080:
2081:                if (TraceTm.jta.isDebugEnabled()) {
2082:                    TraceTm.jta.debug("remove tx from xid (xid=" + xid + ")");
2083:                }
2084:
2085:                txXids.remove(xid);
2086:            }
2087:
2088:            /**
2089:             * remove the Transaction from the ThreadLocal
2090:             */
2091:
2092:            void forget() throws Exception {
2093:                threadTx.set(null);
2094:
2095:                if (TraceTm.jta.isDebugEnabled()) {
2096:                    TraceTm.jta.debug("threadTx.set= null");
2097:                }
2098:            }
2099:
2100:            /* Management methods */
2101:
2102:            /**
2103:             * Returns the current number of transactions.
2104:             * 
2105:             * @return current number of transaction
2106:             */
2107:
2108:            public int getTotalCurrentTransactions() {
2109:                return txXids.size();
2110:            }
2111:
2112:            /**
2113:             * Increments number of begun transactions by one.
2114:             */
2115:
2116:            synchronized void incrementBeginCounter() {
2117:                nb_bg_tx++;
2118:            }
2119:
2120:            /**
2121:             * Returns the total number of begun transactions.
2122:             * 
2123:             * @return total number of begun transactions
2124:             */
2125:
2126:            public int getTotalBegunTransactions() {
2127:                return nb_bg_tx;
2128:            }
2129:
2130:            /**
2131:             * Increments the number of rolled back transaction by one.
2132:             */
2133:
2134:            synchronized void incrementRollbackCounter() {
2135:                nb_rb_tx++;
2136:            }
2137:
2138:            /**
2139:             * Returns the total number of rolled back transactions.
2140:             * 
2141:             * @return total number of rolled back transactions
2142:             */
2143:
2144:            public int getTotalRolledbackTransactions() {
2145:                return nb_rb_tx;
2146:            }
2147:
2148:            /**
2149:             * Increments the number of of committed transactions by one.
2150:             */
2151:
2152:            synchronized void incrementCommitCounter() {
2153:                nb_cm_tx++;
2154:            }
2155:
2156:            /**
2157:             * Returns the total number of committed transactions.
2158:             *
2159:             * @return total number of commited transactions
2160:             */
2161:
2162:            public int getTotalCommittedTransactions() {
2163:                return nb_cm_tx;
2164:            }
2165:
2166:            /**
2167:             * Resets total number of transactions.
2168:             */
2169:
2170:            public synchronized void resetAllTxTotalCounters() {
2171:                nb_bg_tx = 0;
2172:                nb_cm_tx = 0;
2173:                nb_rb_tx = 0;
2174:                nb_to = 0;
2175:            }
2176:
2177:            /**
2178:             * Increments number of rolled back transactions due to timeout by one.
2179:             */
2180:
2181:            synchronized void incrementExpiredCounter() {
2182:                nb_to++;
2183:            }
2184:
2185:            /**
2186:             * Returns the total number of  rolled back transactions due to timeout.
2187:             * 
2188:             * @return number of rolled back transactions due to timeout
2189:             */
2190:
2191:            public int getTotalExpiredTransactions() {
2192:                return nb_to;
2193:            }
2194:
2195:            /**
2196:             * Returns all counters.
2197:             * 
2198:             * @return an array of all counters (current tx, begun tx, committed tx,
2199:             * rolled back tx, timeouted tx)
2200:             */
2201:
2202:            public synchronized Integer[] getTransactionCounters() {
2203:                Integer[] result = new Integer[5];
2204:                result[0] = new Integer(txXids.size());
2205:                result[1] = new Integer(nb_bg_tx);
2206:                result[2] = new Integer(nb_cm_tx);
2207:                result[3] = new Integer(nb_rb_tx);
2208:                result[4] = new Integer(nb_to);
2209:                return result;
2210:            }
2211:
2212:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.