Source Code Cross Referenced for TxManager.java in  » EJB-Server-JBoss-4.2.1 » transaction » org » jboss » tm » 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 » EJB Server JBoss 4.2.1 » transaction » org.jboss.tm 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * JBoss, Home of Professional Open Source.
003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004:         * as indicated by the @author tags. See the copyright.txt file in the
005:         * distribution for a full listing of individual contributors.
006:         *
007:         * This is free software; you can redistribute it and/or modify it
008:         * under the terms of the GNU Lesser General Public License as
009:         * published by the Free Software Foundation; either version 2.1 of
010:         * the License, or (at your option) any later version.
011:         *
012:         * This software is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this software; if not, write to the Free
019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021:         */
022:        package org.jboss.tm;
023:
024:        import java.util.Collections;
025:        import java.util.HashMap;
026:        import java.util.Map;
027:
028:        import javax.resource.spi.work.Work;
029:        import javax.resource.spi.work.WorkCompletedException;
030:        import javax.resource.spi.work.WorkException;
031:        import javax.transaction.HeuristicMixedException;
032:        import javax.transaction.HeuristicRollbackException;
033:        import javax.transaction.InvalidTransactionException;
034:        import javax.transaction.NotSupportedException;
035:        import javax.transaction.RollbackException;
036:        import javax.transaction.Status;
037:        import javax.transaction.SystemException;
038:        import javax.transaction.Transaction;
039:        import javax.transaction.TransactionManager;
040:        import javax.transaction.xa.XAException;
041:        import javax.transaction.xa.Xid;
042:
043:        import org.jboss.logging.Logger;
044:        import org.jboss.tm.integrity.TransactionIntegrity;
045:        import org.jboss.util.UnexpectedThrowable;
046:        import org.jboss.util.UnreachableStatementException;
047:
048:        /**
049:         * Our TransactionManager implementation.
050:         *
051:         * @author <a href="mailto:rickard.oberg@telkel.com">Rickard Öberg</a>
052:         * @author <a href="mailto:marc.fleury@telkel.com">Marc Fleury</a>
053:         * @author <a href="mailto:osh@sparre.dk">Ole Husgaard</a>
054:         * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
055:         * @author <a href="reverbel@ime.usp.br">Francisco Reverbel</a>
056:         * @author <a href="adrian@jboss.com">Adrian Brock</a>
057:         * @author <a href="dimitris@jboss.org">Dimitris Andreadis</a>
058:         * @version $Revision: 57208 $
059:         * @deprecated Do not reference directly, use org.jboss.tm.TransactionManagerLocator
060:         */
061:        public class TxManager implements  TransactionManager,
062:                TransactionPropagationContextImporter,
063:                TransactionPropagationContextFactory, TransactionLocalDelegate,
064:                TransactionTimeoutConfiguration, JBossXATerminator {
065:            // Constants -----------------------------------------------------
066:
067:            // Attributes ----------------------------------------------------
068:
069:            /** True if the TxManager should keep a map from GlobalIds to transactions. */
070:            private boolean globalIdsEnabled = false;
071:
072:            /** Whether to interrupt threads at transaction timeout */
073:            private boolean interruptThreads = false;
074:
075:            /** Instance logger. */
076:            private Logger log = Logger.getLogger(this .getClass());
077:
078:            /** True if trace messages should be logged. */
079:            private boolean trace = log.isTraceEnabled();
080:
081:            /**
082:             *  Default timeout in milliseconds.
083:             *  Must be >= 1000!
084:             */
085:            private long timeOut = 5 * 60 * 1000;
086:
087:            // The following two fields are ints (not longs) because
088:            // volatile 64Bit types are broken (i.e. access is not atomic) in most VMs, and we
089:            // don't want to lock just for a statistic. Additionaly,
090:            // it will take several years on a highly loaded system to
091:            // exceed the int range. Note that we might loose an
092:            // increment every now and then, since the ++ operation is
093:            // not atomic on volatile data types.
094:            /** A count of the transactions that have been committed */
095:            private volatile int commitCount;
096:            /** A count of the transactions that have been rolled back */
097:            private volatile int rollbackCount;
098:
099:            /** The transaction integrity policy */
100:            private TransactionIntegrity integrity;
101:
102:            // Static --------------------------------------------------------
103:
104:            /**
105:             *  The singleton instance.
106:             */
107:            private static TxManager singleton = new TxManager();
108:
109:            /**
110:             *  Get a reference to the singleton instance.
111:             */
112:            public static TxManager getInstance() {
113:                return singleton;
114:            }
115:
116:            // Constructors --------------------------------------------------
117:
118:            /**
119:             *  Private constructor for singleton. Use getInstance() to obtain
120:             *  a reference to the singleton.
121:             */
122:            private TxManager() {
123:                //make sure TxCapsule can be used
124:                TransactionImpl.defaultXidFactory();
125:            }
126:
127:            // Public --------------------------------------------------------
128:
129:            /**
130:             *  Setter for attribute <code>globalIdsEnabled</code>.
131:             */
132:            public void setGlobalIdsEnabled(boolean newValue) {
133:                XidImpl.setTrulyGlobalIdsEnabled(newValue);
134:                globalIdsEnabled = newValue;
135:            }
136:
137:            /**
138:             *  Getter for attribute <code>globalIdsEnabled</code>.
139:             */
140:            public boolean getGlobalIdsEnabled() {
141:                return globalIdsEnabled;
142:            }
143:
144:            /**
145:             * Enable/disable thread interruption at transaction timeout.
146:             * 
147:             * @param interruptThreads pass true to interrupt threads, false otherwise
148:             */
149:            public void setInterruptThreads(boolean interruptThreads) {
150:                this .interruptThreads = interruptThreads;
151:            }
152:
153:            /**
154:             * Is thread interruption enabled at transaction timeout
155:             * 
156:             * @return true for interrupt threads, false otherwise
157:             */
158:            public boolean isInterruptThreads() {
159:                return interruptThreads;
160:            }
161:
162:            /**
163:             * Set the transaction integrity policy
164:             * 
165:             * @param integrity the transaction integrity policy
166:             */
167:            public void setTransactionIntegrity(TransactionIntegrity integrity) {
168:                this .integrity = integrity;
169:            }
170:
171:            /**
172:             * Get the transaction integrity policy
173:             * 
174:             * @return the transaction integrity policy
175:             */
176:            public TransactionIntegrity getTransactionIntegrity() {
177:                return integrity;
178:            }
179:
180:            /**
181:             *  Begin a new transaction.
182:             *  The new transaction will be associated with the calling thread.
183:             */
184:            public void begin() throws NotSupportedException, SystemException {
185:                trace = log.isTraceEnabled();
186:
187:                ThreadInfo ti = getThreadInfo();
188:                TransactionImpl current = ti.tx;
189:
190:                if (current != null) {
191:                    if (current.isDone())
192:                        disassociateThread(ti);
193:                    else
194:                        throw new NotSupportedException(
195:                                "Transaction already active, cannot nest transactions.");
196:                }
197:
198:                long timeout = (ti.timeout == 0) ? timeOut : ti.timeout;
199:                TransactionImpl tx = new TransactionImpl(timeout);
200:                associateThread(ti, tx);
201:                localIdTx.put(tx.getLocalId(), tx);
202:                if (globalIdsEnabled)
203:                    globalIdTx.put(tx.getGlobalId(), tx);
204:
205:                if (trace)
206:                    log.trace("began tx: " + tx);
207:            }
208:
209:            /**
210:             *  Commit the transaction associated with the currently running thread.
211:             */
212:            public void commit() throws RollbackException,
213:                    HeuristicMixedException, HeuristicRollbackException,
214:                    SecurityException, IllegalStateException, SystemException {
215:                ThreadInfo ti = getThreadInfo();
216:                TransactionImpl current = ti.tx;
217:
218:                if (current != null) {
219:                    current.commit();
220:                    disassociateThread(ti);
221:                    if (trace)
222:                        log.trace("commited tx: " + current);
223:                } else
224:                    throw new IllegalStateException("No transaction.");
225:            }
226:
227:            /**
228:             *  Return the status of the transaction associated with the currently
229:             *  running thread, or <code>Status.STATUS_NO_TRANSACTION</code> if no
230:             *  active transaction is currently associated.
231:             */
232:            public int getStatus() throws SystemException {
233:                ThreadInfo ti = getThreadInfo();
234:                TransactionImpl current = ti.tx;
235:
236:                if (current != null) {
237:                    if (current.isDone())
238:                        disassociateThread(ti);
239:                    else
240:                        return current.getStatus();
241:                }
242:                return Status.STATUS_NO_TRANSACTION;
243:            }
244:
245:            /**
246:             *  Return the transaction currently associated with the invoking thread,
247:             *  or <code>null</code> if no active transaction is currently associated.
248:             */
249:            public Transaction getTransaction() throws SystemException {
250:                ThreadInfo ti = getThreadInfo();
251:                TransactionImpl current = ti.tx;
252:
253:                if (current != null && current.isDone()) {
254:                    current = null;
255:                    disassociateThread(ti);
256:                }
257:
258:                return current;
259:            }
260:
261:            /**
262:             *  Resume a transaction.
263:             *
264:             *  Note: This will not enlist any resources involved in this
265:             *  transaction. According to JTA1.0.1 specification section 3.2.3,
266:             *  that is the responsibility of the application server.
267:             */
268:            public void resume(Transaction transaction)
269:                    throws InvalidTransactionException, IllegalStateException,
270:                    SystemException {
271:                if (transaction != null
272:                        && !(transaction instanceof  TransactionImpl))
273:                    throw new RuntimeException("Not a TransactionImpl, but a "
274:                            + transaction.getClass().getName());
275:
276:                ThreadInfo ti = getThreadInfo();
277:                TransactionImpl current = ti.tx;
278:
279:                if (current != null) {
280:                    if (current.isDone())
281:                        current = ti.tx = null;
282:                    else
283:                        throw new IllegalStateException(
284:                                "Already associated with a tx");
285:                }
286:
287:                if (current != transaction) {
288:                    associateThread(ti, (TransactionImpl) transaction);
289:                }
290:
291:                if (trace)
292:                    log.trace("resumed tx: " + ti.tx);
293:            }
294:
295:            /**
296:             *  Suspend the transaction currently associated with the current
297:             *  thread, and return it.
298:             *
299:             *  Note: This will not delist any resources involved in this
300:             *  transaction. According to JTA1.0.1 specification section 3.2.3,
301:             *  that is the responsibility of the application server.
302:             */
303:            public Transaction suspend() throws SystemException {
304:                ThreadInfo ti = getThreadInfo();
305:                TransactionImpl current = ti.tx;
306:
307:                if (current != null) {
308:                    current.disassociateCurrentThread();
309:                    ti.tx = null;
310:
311:                    if (trace)
312:                        log.trace("suspended tx: " + current);
313:
314:                    if (current.isDone())
315:                        current = null;
316:                }
317:
318:                return current;
319:            }
320:
321:            /**
322:             *  Roll back the transaction associated with the currently running thread.
323:             */
324:            public void rollback() throws IllegalStateException,
325:                    SecurityException, SystemException {
326:                ThreadInfo ti = getThreadInfo();
327:                TransactionImpl current = ti.tx;
328:
329:                if (current != null) {
330:                    if (!current.isDone()) {
331:                        current.rollback();
332:
333:                        if (trace)
334:                            log.trace("rolled back tx: " + current);
335:                        return;
336:                    }
337:                    disassociateThread(ti);
338:                }
339:                throw new IllegalStateException("No transaction.");
340:            }
341:
342:            /**
343:             *  Mark the transaction associated with the currently running thread
344:             *  so that the only possible outcome is a rollback.
345:             */
346:            public void setRollbackOnly() throws IllegalStateException,
347:                    SystemException {
348:                ThreadInfo ti = getThreadInfo();
349:                TransactionImpl current = ti.tx;
350:
351:                if (current != null) {
352:                    if (!current.isDone()) {
353:                        current.setRollbackOnly();
354:
355:                        if (trace)
356:                            log
357:                                    .trace("tx marked for rollback only: "
358:                                            + current);
359:                        return;
360:                    }
361:                    ti.tx = null;
362:                }
363:                throw new IllegalStateException("No transaction.");
364:            }
365:
366:            public int getTransactionTimeout() {
367:                return (int) (getThreadInfo().timeout / 1000);
368:            }
369:
370:            /**
371:             *  Set the transaction timeout for new transactions started by the
372:             *  calling thread.
373:             */
374:            public void setTransactionTimeout(int seconds)
375:                    throws SystemException {
376:                getThreadInfo().timeout = 1000 * seconds;
377:
378:                if (trace)
379:                    log.trace("tx timeout is now: " + seconds + "s");
380:            }
381:
382:            /**
383:             *  Set the default transaction timeout for new transactions.
384:             *  This default value is used if <code>setTransactionTimeout()</code>
385:             *  was never called, or if it was called with a value of <code>0</code>.
386:             */
387:            public void setDefaultTransactionTimeout(int seconds) {
388:                timeOut = 1000L * seconds;
389:
390:                if (trace)
391:                    log.trace("default tx timeout is now: " + seconds + "s");
392:            }
393:
394:            /**
395:             *  Get the default transaction timeout.
396:             *
397:             *  @return Default transaction timeout in seconds.
398:             */
399:            public int getDefaultTransactionTimeout() {
400:                return (int) (timeOut / 1000);
401:            }
402:
403:            public long getTimeLeftBeforeTransactionTimeout(
404:                    boolean errorRollback) throws RollbackException {
405:                try {
406:                    ThreadInfo ti = getThreadInfo();
407:                    TransactionImpl current = ti.tx;
408:                    if (current != null && current.isDone()) {
409:                        disassociateThread(ti);
410:                        return -1;
411:                    }
412:                    return current.getTimeLeftBeforeTimeout(errorRollback);
413:                } catch (RollbackException e) {
414:                    throw e;
415:                } catch (Exception ignored) {
416:                    return -1;
417:                }
418:            }
419:
420:            /**
421:             *  The following 2 methods are here to provide association and
422:             *  disassociation of the thread.
423:             */
424:            public Transaction disassociateThread() {
425:                return disassociateThread(getThreadInfo());
426:            }
427:
428:            private Transaction disassociateThread(ThreadInfo ti) {
429:                TransactionImpl current = ti.tx;
430:                ti.tx = null;
431:                current.disassociateCurrentThread();
432:                return current;
433:            }
434:
435:            public void associateThread(Transaction transaction) {
436:                if (transaction != null
437:                        && !(transaction instanceof  TransactionImpl))
438:                    throw new RuntimeException("Not a TransactionImpl, but a "
439:                            + transaction.getClass().getName());
440:
441:                // Associate with the thread
442:                TransactionImpl transactionImpl = (TransactionImpl) transaction;
443:                ThreadInfo ti = getThreadInfo();
444:                ti.tx = transactionImpl;
445:                transactionImpl.associateCurrentThread();
446:            }
447:
448:            private void associateThread(ThreadInfo ti,
449:                    TransactionImpl transaction) {
450:                // Associate with the thread
451:                ti.tx = transaction;
452:                transaction.associateCurrentThread();
453:            }
454:
455:            /**
456:             * Return the number of active transactions
457:             */
458:            public int getTransactionCount() {
459:                return localIdTx.size();
460:            }
461:
462:            /** A count of the transactions that have been committed */
463:            public long getCommitCount() {
464:                return commitCount;
465:            }
466:
467:            /** A count of the transactions that have been rolled back */
468:            public long getRollbackCount() {
469:                return rollbackCount;
470:            }
471:
472:            // Implements TransactionPropagationContextImporter ---------------
473:
474:            /**
475:             *  Import a transaction propagation context into this TM.
476:             *  The TPC is loosely typed, as we may (at a later time) want to
477:             *  import TPCs that come from other transaction domains without
478:             *  offloading the conversion to the client.
479:             *
480:             *  @param tpc The transaction propagation context that we want to
481:             *             import into this TM. Currently this is an instance
482:             *             of LocalId. At some later time this may be an instance
483:             *             of a transaction propagation context from another
484:             *             transaction domain like
485:             *             org.omg.CosTransactions.PropagationContext.
486:             *
487:             *  @return A transaction representing this transaction propagation
488:             *          context, or null if this TPC cannot be imported.
489:             */
490:            public Transaction importTransactionPropagationContext(Object tpc) {
491:                if (tpc instanceof  LocalId) {
492:                    LocalId id = (LocalId) tpc;
493:                    return (Transaction) localIdTx.get(id);
494:                } else if (globalIdsEnabled && tpc instanceof  GlobalId) {
495:                    GlobalId id = (GlobalId) tpc;
496:                    Transaction tx = (Transaction) globalIdTx.get(id);
497:                    if (trace) {
498:                        if (tx != null)
499:                            log
500:                                    .trace("Successfully imported transaction context "
501:                                            + tpc);
502:                        else
503:                            log.trace("Could not import transaction context "
504:                                    + tpc);
505:                    }
506:                    return tx;
507:                }
508:
509:                log.warn("Cannot import transaction propagation context: "
510:                        + tpc);
511:                return null;
512:            }
513:
514:            // Implements TransactionPropagationContextFactory ---------------
515:
516:            /**
517:             *  Return a TPC for the current transaction.
518:             */
519:            public Object getTransactionPropagationContext() {
520:                return getTransactionPropagationContext(getThreadInfo().tx);
521:            }
522:
523:            /**
524:             *  Return a TPC for the argument transaction.
525:             */
526:            public Object getTransactionPropagationContext(Transaction tx) {
527:                // If no transaction or unknown transaction class, return null.
528:                if (tx == null)
529:                    return null;
530:                if (!(tx instanceof  TransactionImpl)) {
531:                    log.warn("Cannot export transaction propagation context: "
532:                            + tx);
533:                    return null;
534:                }
535:
536:                return ((TransactionImpl) tx).getLocalId();
537:            }
538:
539:            // Implements XATerminator ----------------------------------
540:
541:            public void registerWork(Work work, Xid xid, long timeout)
542:                    throws WorkCompletedException {
543:                if (trace)
544:                    log.trace("registering work=" + work + " xid=" + xid
545:                            + " timeout=" + timeout);
546:                try {
547:                    TransactionImpl tx = importExternalTransaction(xid, timeout);
548:                    tx.setWork(work);
549:                } catch (WorkCompletedException e) {
550:                    throw e;
551:                } catch (Throwable t) {
552:                    WorkCompletedException e = new WorkCompletedException(
553:                            "Error registering work", t);
554:                    e.setErrorCode(WorkException.TX_RECREATE_FAILED);
555:                    throw e;
556:                }
557:                if (trace)
558:                    log.trace("registered work= " + work + " xid=" + xid
559:                            + " timeout=" + timeout);
560:            }
561:
562:            public void startWork(Work work, Xid xid)
563:                    throws WorkCompletedException {
564:                if (trace)
565:                    log.trace("starting work=" + work + " xid=" + xid);
566:                TransactionImpl tx = getExternalTransaction(xid);
567:                associateThread(tx);
568:                if (trace)
569:                    log.trace("started work= " + work + " xid=" + xid);
570:            }
571:
572:            public void endWork(Work work, Xid xid) {
573:                if (trace)
574:                    log.trace("ending work=" + work + " xid=" + xid);
575:                try {
576:                    TransactionImpl tx = getExternalTransaction(xid);
577:                    tx.setWork(null);
578:                    disassociateThread();
579:                } catch (WorkCompletedException e) {
580:                    log.error("Unexpected error from endWork ", e);
581:                    throw new UnexpectedThrowable(e.toString());
582:                }
583:                if (trace)
584:                    log.trace("ended work=" + work + " xid=" + xid);
585:            }
586:
587:            public void cancelWork(Work work, Xid xid) {
588:                if (trace)
589:                    log.trace("cancling work=" + work + " xid=" + xid);
590:                try {
591:                    TransactionImpl tx = getExternalTransaction(xid);
592:                    tx.setWork(null);
593:                } catch (WorkCompletedException e) {
594:                    log.error("Unexpected error from cancelWork ", e);
595:                    throw new UnexpectedThrowable(e.toString());
596:                }
597:                if (trace)
598:                    log.trace("cancled work=" + work + " xid=" + xid);
599:            }
600:
601:            public int prepare(Xid xid) throws XAException {
602:                if (trace)
603:                    log.trace("preparing xid=" + xid);
604:                try {
605:                    TransactionImpl tx = getExternalTransaction(xid);
606:                    int result = tx.prepare();
607:                    if (trace)
608:                        log.trace("prepared xid=" + xid + " result=" + result);
609:                    return result;
610:                } catch (Throwable t) {
611:                    JBossXAException.rethrowAsXAException(
612:                            "Error during prepare", t);
613:                    throw new UnreachableStatementException();
614:                }
615:            }
616:
617:            public void rollback(Xid xid) throws XAException {
618:                if (trace)
619:                    log.trace("rolling back xid=" + xid);
620:                try {
621:                    TransactionImpl tx = getExternalTransaction(xid);
622:                    tx.rollback();
623:                } catch (Throwable t) {
624:                    JBossXAException.rethrowAsXAException(
625:                            "Error during rollback", t);
626:                }
627:                if (trace)
628:                    log.trace("rolled back xid=" + xid);
629:            }
630:
631:            public void commit(Xid xid, boolean onePhase) throws XAException {
632:                if (trace)
633:                    log
634:                            .trace("committing xid=" + xid + " onePhase="
635:                                    + onePhase);
636:                try {
637:                    TransactionImpl tx = getExternalTransaction(xid);
638:                    tx.commit(onePhase);
639:                } catch (Throwable t) {
640:                    JBossXAException.rethrowAsXAException(
641:                            "Error during commit", t);
642:                }
643:                if (trace)
644:                    log.trace("committed xid=" + xid);
645:            }
646:
647:            public void forget(Xid xid) throws XAException {
648:                if (trace)
649:                    log.trace("forgetting xid=" + xid);
650:                try {
651:                    TransactionImpl tx = getExternalTransaction(xid);
652:                    tx.rollback();
653:                } catch (Throwable t) {
654:                    JBossXAException.rethrowAsXAException(
655:                            "Error during forget", t);
656:                }
657:                if (trace)
658:                    log.trace("forgot xid=" + xid);
659:            }
660:
661:            public Xid[] recover(int flag) throws XAException {
662:                // TODO recover
663:                return new Xid[0];
664:            }
665:
666:            TransactionImpl importExternalTransaction(Xid xid, long timeOut) {
667:                GlobalId gid = new GlobalId(xid);
668:                TransactionImpl tx = (TransactionImpl) globalIdTx.get(gid);
669:                if (tx != null) {
670:                    if (trace)
671:                        log.trace("imported existing transaction xid: " + xid
672:                                + " tx=" + tx);
673:                } else {
674:                    ThreadInfo ti = getThreadInfo();
675:                    long timeout = (ti.timeout == 0) ? timeOut : ti.timeout;
676:                    tx = new TransactionImpl(gid, timeout);
677:                    localIdTx.put(tx.getLocalId(), tx);
678:                    if (globalIdsEnabled)
679:                        globalIdTx.put(gid, tx);
680:
681:                    if (trace)
682:                        log.trace("imported new transaction xid: " + xid
683:                                + " tx=" + tx + " timeout=" + timeout);
684:                }
685:                return tx;
686:            }
687:
688:            TransactionImpl getExternalTransaction(Xid xid)
689:                    throws WorkCompletedException {
690:                GlobalId gid = new GlobalId(xid);
691:                TransactionImpl tx = (TransactionImpl) globalIdTx.get(gid);
692:                if (tx == null)
693:                    throw new WorkCompletedException("Xid not found " + xid,
694:                            WorkException.TX_RECREATE_FAILED);
695:                return tx;
696:            }
697:
698:            // Implements TransactionLocalDelegate ----------------------
699:
700:            public void lock(TransactionLocal local, Transaction tx)
701:                    throws InterruptedException {
702:                TransactionImpl tximpl = (TransactionImpl) tx;
703:                tximpl.lock();
704:            }
705:
706:            public void unlock(TransactionLocal local, Transaction tx) {
707:                TransactionImpl tximpl = (TransactionImpl) tx;
708:                tximpl.unlock();
709:            }
710:
711:            public Object getValue(TransactionLocal local, Transaction tx) {
712:                TransactionImpl tximpl = (TransactionImpl) tx;
713:                return tximpl.getTransactionLocalValue(local);
714:            }
715:
716:            public void storeValue(TransactionLocal local, Transaction tx,
717:                    Object value) {
718:                TransactionImpl tximpl = (TransactionImpl) tx;
719:                tximpl.putTransactionLocalValue(local, value);
720:            }
721:
722:            public boolean containsValue(TransactionLocal local, Transaction tx) {
723:                TransactionImpl tximpl = (TransactionImpl) tx;
724:                return tximpl.containsTransactionLocal(local);
725:            }
726:
727:            // Package protected ---------------------------------------------
728:
729:            /**
730:             *  Release the given TransactionImpl.
731:             */
732:            void releaseTransactionImpl(TransactionImpl tx) {
733:                localIdTx.remove(tx.getLocalId());
734:                if (globalIdsEnabled)
735:                    globalIdTx.remove(tx.getGlobalId());
736:            }
737:
738:            /**
739:             * Increment the commit count
740:             */
741:            void incCommitCount() {
742:                ++commitCount;
743:            }
744:
745:            /**
746:             * Increment the rollback count
747:             */
748:            void incRollbackCount() {
749:                ++rollbackCount;
750:            }
751:
752:            // Protected -----------------------------------------------------
753:
754:            // Private -------------------------------------------------------
755:
756:            /**
757:             *  This keeps track of the thread association with transactions
758:             *  and timeout values.
759:             *  In some cases terminated transactions may not be cleared here.
760:             */
761:            private ThreadLocal threadTx = new ThreadLocal();
762:
763:            /**
764:             *  This map contains the active transactions as values.
765:             *  The keys are the <code>LocalId</code>s of the transactions.
766:             */
767:            private Map localIdTx = Collections.synchronizedMap(new HashMap());
768:
769:            /**
770:             *  If <code>globalIdsEnabled</code> is true, this map associates
771:             *  <code>GlobalId</code>s to active transactions. 
772:             */
773:            private Map globalIdTx = Collections.synchronizedMap(new HashMap());
774:
775:            /**
776:             *  Return the ThreadInfo for the calling thread, and create if not
777:             *  found.
778:             */
779:            private ThreadInfo getThreadInfo() {
780:                ThreadInfo ret = (ThreadInfo) threadTx.get();
781:
782:                if (ret == null) {
783:                    ret = new ThreadInfo();
784:                    ret.timeout = timeOut;
785:                    threadTx.set(ret);
786:                }
787:
788:                return ret;
789:            }
790:
791:            // Inner classes -------------------------------------------------
792:
793:            /**
794:             *  A simple aggregate of a thread-associated timeout value
795:             *  and a thread-associated transaction.
796:             */
797:            static class ThreadInfo {
798:                long timeout;
799:                TransactionImpl tx;
800:            }
801:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.