Source Code Cross Referenced for EjbTransactionManager.java in  » EJB-Server-resin-3.1.5 » resin » com » caucho » ejb » xa » 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 resin 3.1.5 » resin » com.caucho.ejb.xa 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003:         *
004:         * This file is part of Resin(R) Open Source
005:         *
006:         * Each copy or derived work must preserve the copyright notice and this
007:         * notice unmodified.
008:         *
009:         * Resin Open Source is free software; you can redistribute it and/or modify
010:         * it under the terms of the GNU General Public License as published by
011:         * the Free Software Foundation; either version 2 of the License, or
012:         * (at your option) any later version.
013:         *
014:         * Resin Open Source is distributed in the hope that it will be useful,
015:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
016:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017:         * of NON-INFRINGEMENT.  See the GNU General Public License for more
018:         * details.
019:         *
020:         * You should have received a copy of the GNU General Public License
021:         * along with Resin Open Source; if not, write to the
022:         *   Free SoftwareFoundation, Inc.
023:         *   59 Temple Place, Suite 330
024:         *   Boston, MA 02111-1307  USA
025:         *
026:         * @author Scott Ferguson
027:         */
028:
029:        package com.caucho.ejb.xa;
030:
031:        import com.caucho.amber.manager.AmberConnection;
032:        import com.caucho.config.ConfigException;
033:        import com.caucho.ejb.EJBExceptionWrapper;
034:        import com.caucho.ejb.manager.EjbContainer;
035:        import com.caucho.log.Log;
036:        import com.caucho.util.FreeList;
037:        import com.caucho.util.L10N;
038:
039:        import javax.ejb.EJBException;
040:        import javax.ejb.EJBTransactionRequiredException;
041:        import javax.naming.InitialContext;
042:        import javax.naming.NamingException;
043:        import javax.transaction.Transaction;
044:        import javax.transaction.TransactionManager;
045:        import javax.transaction.UserTransaction;
046:        import java.util.Hashtable;
047:        import java.util.logging.Level;
048:        import java.util.logging.Logger;
049:
050:        /**
051:         * Server containing all the EJBs for a given configuration.
052:         *
053:         * <p>Each protocol will extend the container to override Handle creation.
054:         */
055:        public class EjbTransactionManager implements  java.io.Serializable {
056:            private static final L10N L = new L10N(EjbTransactionManager.class);
057:            private static final Logger log = Log
058:                    .open(EjbTransactionManager.class);
059:
060:            public static final int RESIN_DATABASE = 0;
061:            public static final int RESIN_READ_ONLY = 1;
062:            public static final int RESIN_ROW_LOCKING = 2;
063:
064:            protected static final ThreadLocal<TransactionContext> _threadTransaction = new ThreadLocal<TransactionContext>();
065:
066:            private FreeList<TransactionContext> _freeTransactions = new FreeList<TransactionContext>(
067:                    64);
068:
069:            private Hashtable<Transaction, TransactionContext> _transactionMap = new Hashtable<Transaction, TransactionContext>();
070:
071:            private Hashtable<String, TransactionContext> _foreignTransactionMap = new Hashtable<String, TransactionContext>();
072:
073:            private final EjbContainer _ejbContainer;
074:
075:            protected final TransactionManager _transactionManager;
076:            protected UserTransaction _userTransaction;
077:
078:            private int _resinIsolation = -1;
079:            private int _jdbcIsolation = -1;
080:
081:            private long _transactionTimeout = 0;
082:
083:            private boolean _isClosed;
084:
085:            private boolean _isEJB3;
086:
087:            /**
088:             * Create a server with the given prefix name.
089:             */
090:            public EjbTransactionManager(EjbContainer ejbContainer)
091:                    throws ConfigException {
092:                _ejbContainer = ejbContainer;
093:
094:                UserTransaction ut = null;
095:                TransactionManager tm = null;
096:
097:                try {
098:                    InitialContext ic = new InitialContext();
099:
100:                    ut = (UserTransaction) ic
101:                            .lookup("java:comp/UserTransaction");
102:
103:                    tm = (TransactionManager) ic
104:                            .lookup("java:comp/TransactionManager");
105:                } catch (NamingException e) {
106:                    log.log(Level.WARNING, e.toString(), e);
107:                }
108:
109:                _userTransaction = ut;
110:                _transactionManager = tm;
111:
112:                if (_transactionManager == null)
113:                    throw new ConfigException(L
114:                            .l("Can't load TransactionManager."));
115:            }
116:
117:            /**
118:             * Returns the manager.
119:             */
120:            public EjbContainer getEjbContainer() {
121:                return _ejbContainer;
122:            }
123:
124:            /**
125:             * Sets EJB 3.0 for throwing expected exceptions.
126:             */
127:            public void setEJB3(boolean isEJB3) {
128:                _isEJB3 = isEJB3;
129:            }
130:
131:            /**
132:             * Returns true if it is EJB 3.0
133:             */
134:            public boolean isEJB3() {
135:                return _isEJB3;
136:            }
137:
138:            /**
139:             * Sets the Resin isolation.
140:             */
141:            public void setResinIsolation(int resinIsolation) {
142:                _resinIsolation = resinIsolation;
143:            }
144:
145:            /**
146:             * Sets the Resin isolation for the container.
147:             */
148:            public int getResinIsolation() {
149:                return _resinIsolation;
150:            }
151:
152:            /**
153:             * Sets the JDBC isolation.
154:             */
155:            public void setJDBCIsolation(int jdbcIsolation) {
156:                _jdbcIsolation = jdbcIsolation;
157:            }
158:
159:            /**
160:             * Gets the JDBC isolation level.
161:             */
162:            public int getJDBCIsolation() {
163:                return _jdbcIsolation;
164:            }
165:
166:            /**
167:             * Gets the transaction timeout
168:             */
169:            public long getTransactionTimeout() {
170:                return _transactionTimeout;
171:            }
172:
173:            /**
174:             * Sets the transaction timout.
175:             */
176:            public void setTransactionTimeout(long transactionTimeout) {
177:                _transactionTimeout = transactionTimeout;
178:            }
179:
180:            void setUserTransaction(UserTransaction userTransaction) {
181:                _userTransaction = userTransaction;
182:            }
183:
184:            public UserTransaction getUserTransaction() {
185:                return _userTransaction;
186:            }
187:
188:            /**
189:             * Returns a new AmberConnection.
190:             */
191:            public AmberConnection getAmberConnection() {
192:                TransactionContext xaContext = _threadTransaction.get();
193:
194:                if (xaContext != null)
195:                    return xaContext.getAmberConnection();
196:                else
197:                    throw new IllegalStateException(
198:                            "can't get transaction outside of context");
199:            }
200:
201:            public void commitTransaction() throws EJBException {
202:                try {
203:                    if (_transactionManager.getTransaction() != null)
204:                        _userTransaction.commit();
205:                } catch (Exception e) {
206:                    throw EJBExceptionWrapper.create(e);
207:                }
208:            }
209:
210:            public void rollbackTransaction() throws EJBException {
211:                try {
212:                    _userTransaction.rollback();
213:                } catch (Exception e) {
214:                    throw EJBExceptionWrapper.create(e);
215:                }
216:            }
217:
218:            TransactionManager getTransactionManager() throws EJBException {
219:                return _transactionManager;
220:            }
221:
222:            public Transaction getTransaction() throws EJBException {
223:                try {
224:                    return _transactionManager.getTransaction();
225:                } catch (Exception e) {
226:                    throw EJBExceptionWrapper.create(e);
227:                }
228:            }
229:
230:            public TransactionContext getTransactionContext() {
231:                return _threadTransaction.get();
232:            }
233:
234:            /**
235:             * Returns a transaction context for the "required" transaction.  If
236:             * there's already an active transaction, use it.  Otherwise create a
237:             * new transaction.
238:             *
239:             * @return the transaction context for the request
240:             */
241:            public TransactionContext beginRequired() throws EJBException {
242:                try {
243:                    Transaction oldTrans = _transactionManager.getTransaction();
244:                    TransactionContext oldCxt = _threadTransaction.get();
245:
246:                    // If this is within the same EJB transaction, just bump
247:                    // the count
248:                    if (oldCxt != null && oldTrans != null
249:                            && oldCxt.getTransaction() == oldTrans) {
250:                        oldCxt.pushDepth();
251:                        return oldCxt;
252:                    }
253:
254:                    // If there's an old transaction, see if there's a transaction context
255:                    // (only needed to support suspends)
256:
257:                    if (oldTrans != null) {
258:                        TransactionContext cxt = _transactionMap.get(oldTrans);
259:
260:                        if (cxt != null) {
261:                            _transactionMap.remove(oldTrans);
262:
263:                            _threadTransaction.set(cxt);
264:                            cxt.pushDepth();
265:
266:                            return cxt;
267:                        }
268:                    }
269:
270:                    // Link the new context to any old context
271:                    TransactionContext cxt = createTransaction();
272:                    cxt.setOld(oldCxt);
273:
274:                    _threadTransaction.set(cxt);
275:                    // If there was an old transaction, use it
276:                    if (oldTrans != null) {
277:                        setTransaction(cxt, oldTrans);
278:                        // This context is controlled by a user transaction
279:                        cxt.setUserTransaction(true);
280:                        cxt.pushDepth();
281:                    } else {
282:                        _userTransaction
283:                                .setTransactionTimeout((int) (_transactionTimeout / 1000L));
284:                        _userTransaction.begin();
285:                        Transaction trans = _transactionManager
286:                                .getTransaction();
287:
288:                        setTransaction(cxt, trans);
289:                    }
290:
291:                    if (_resinIsolation == RESIN_ROW_LOCKING)
292:                        cxt.setRowLocking(true);
293:
294:                    return cxt;
295:                } catch (Exception e) {
296:                    log.log(Level.WARNING, e.toString(), e);
297:
298:                    throw EJBExceptionWrapper.create(e);
299:                }
300:            }
301:
302:            /**
303:             * Returns a transaction context for a single read call.  The single
304:             * read is like supports, but returns a null transaction context
305:             * if there's no transaction.
306:             *
307:             * @return the transaction context for the request
308:             */
309:            public TransactionContext beginSingleRead() throws EJBException {
310:                try {
311:                    TransactionContext cxt = _threadTransaction.get();
312:                    Transaction trans = _transactionManager.getTransaction();
313:
314:                    if (trans == null)
315:                        return null;
316:
317:                    // If in the same EJB transaction, return it
318:                    if (cxt != null && cxt.getTransaction() == trans) {
319:                        cxt.pushDepth();
320:                        return cxt;
321:                    }
322:
323:                    // Check to see if there's an old EJB transaction to handle resume()
324:                    TransactionContext newCxt = _transactionMap.get(trans);
325:
326:                    if (newCxt != null) {
327:                        newCxt.pushDepth();
328:                        return newCxt;
329:                    }
330:
331:                    // Create a new EJB context and link to any old context
332:                    newCxt = createTransaction();
333:                    newCxt.pushDepth();
334:
335:                    _threadTransaction.set(newCxt);
336:                    setTransaction(newCxt, trans);
337:                    // The transaction is controlled by a user transaction
338:                    newCxt.setUserTransaction(true);
339:
340:                    return newCxt;
341:                } catch (Exception e) {
342:                    log.log(Level.WARNING, e.toString(), e);
343:
344:                    throw EJBExceptionWrapper.create(e);
345:                }
346:            }
347:
348:            /**
349:             * Begins a new transaction, suspending the old one if necessary.
350:             *
351:             * @return the old transaction context
352:             */
353:            public TransactionContext beginRequiresNew() throws EJBException {
354:                try {
355:                    TransactionContext oldCxt = _threadTransaction.get();
356:                    Transaction oldTrans = _transactionManager.suspend();
357:
358:                    TransactionContext newCxt = createTransaction();
359:                    newCxt.setOld(oldCxt);
360:                    newCxt.setOldTrans(oldTrans);
361:
362:                    _threadTransaction.set(newCxt);
363:
364:                    if (_resinIsolation == RESIN_ROW_LOCKING)
365:                        newCxt.setRowLocking(true);
366:
367:                    _userTransaction
368:                            .setTransactionTimeout((int) (_transactionTimeout / 1000L));
369:                    _userTransaction.begin();
370:                    Transaction trans = _transactionManager.getTransaction();
371:
372:                    setTransaction(newCxt, trans);
373:
374:                    return newCxt;
375:                } catch (Exception e) {
376:                    log.log(Level.WARNING, e.toString(), e);
377:
378:                    throw EJBExceptionWrapper.create(e);
379:                }
380:            }
381:
382:            /**
383:             * Begins a new transaction, suspending the old one if necessary.
384:             *
385:             * @return the old transaction context
386:             */
387:            public TransactionContext beginSupports() throws EJBException {
388:                try {
389:                    Transaction trans = _transactionManager.getTransaction();
390:                    TransactionContext cxt = _threadTransaction.get();
391:
392:                    // Create a new EJB transaction if necessary
393:                    if (cxt == null || cxt.getTransaction() != trans) {
394:                        // check for a suspended transaction
395:                        if (trans != null)
396:                            cxt = _transactionMap.get(trans);
397:                        else
398:                            cxt = null;
399:
400:                        if (cxt == null) {
401:                            cxt = createTransactionNoDepth();
402:                            setTransaction(cxt, trans);
403:                        }
404:
405:                        _threadTransaction.set(cxt);
406:
407:                        if (trans != null) {
408:                            cxt.setUserTransaction(true);
409:                            cxt.pushDepth();
410:                        }
411:                    }
412:
413:                    cxt.pushDepth();
414:
415:                    if (_resinIsolation == RESIN_ROW_LOCKING)
416:                        cxt.setRowLocking(true);
417:
418:                    return cxt;
419:                } catch (Exception e) {
420:                    log.log(Level.WARNING, e.toString(), e);
421:
422:                    throw EJBExceptionWrapper.create(e);
423:                }
424:            }
425:
426:            /**
427:             * Suspends the current transaction
428:             *
429:             * @return the old transaction context
430:             */
431:            public TransactionContext suspend() throws EJBException {
432:                try {
433:                    TransactionContext oldCxt = _threadTransaction.get();
434:                    Transaction oldTrans = _transactionManager.suspend();
435:
436:                    if (oldTrans == null && oldCxt != null) {
437:                        oldCxt.pushDepth();
438:                        return oldCxt;
439:                    }
440:
441:                    TransactionContext cxt = createTransaction();
442:                    _threadTransaction.set(cxt);
443:
444:                    cxt.setOld(oldCxt);
445:                    cxt.setOldTrans(oldTrans);
446:
447:                    return cxt;
448:                } catch (Exception e) {
449:                    log.log(Level.WARNING, e.toString(), e);
450:
451:                    throw EJBExceptionWrapper.create(e);
452:                }
453:            }
454:
455:            /**
456:             * Starts a Never transaction, i.e. there is no transaction.
457:             *
458:             * @return the old transaction context
459:             */
460:            public TransactionContext beginNever() throws EJBException {
461:                try {
462:                    Transaction oldTrans = _transactionManager.getTransaction();
463:
464:                    if (oldTrans != null)
465:                        throw new EJBException(
466:                                "Transaction forbidden in 'Never' method");
467:
468:                    TransactionContext cxt = _threadTransaction.get();
469:
470:                    if (cxt == null) {
471:                        cxt = createTransaction();
472:                        _threadTransaction.set(cxt);
473:                    } else
474:                        cxt.pushDepth();
475:
476:                    return cxt;
477:                } catch (Exception e) {
478:                    log.log(Level.WARNING, e.toString(), e);
479:
480:                    throw EJBExceptionWrapper.create(e);
481:                }
482:            }
483:
484:            /**
485:             * Begins a new transaction, the old one must exist.
486:             *
487:             * @return the old transaction context
488:             */
489:            public TransactionContext beginMandatory() throws EJBException {
490:                try {
491:                    Transaction trans = _transactionManager.getTransaction();
492:
493:                    if (trans == null) {
494:                        // XXX: check ejb/02a0
495:                        // TCK ejb30/tx: ejb/0f14 vs ejb/02a0
496:                        if (isEJB3())
497:                            throw new EJBTransactionRequiredException(
498:                                    "Transaction required in 'Mandatory' method");
499:                        else
500:                            throw new EJBException(
501:                                    "Transaction required in 'Mandatory' method");
502:                    }
503:
504:                    return beginRequired();
505:                } catch (Exception e) {
506:                    log.log(Level.WARNING, e.toString(), e);
507:
508:                    throw EJBExceptionWrapper.create(e);
509:                }
510:            }
511:
512:            /**
513:             * Resumes a suspended transaction.
514:             *
515:             * @return the old transaction context
516:             */
517:            public void resume(TransactionContext oldCxt, Transaction oldTrans,
518:                    Transaction completedTransaction) throws EJBException {
519:                try {
520:                    if (completedTransaction != null)
521:                        _transactionMap.remove(completedTransaction);
522:                    _threadTransaction.set(oldCxt);
523:
524:                    if (oldTrans != null)
525:                        _transactionManager.resume(oldTrans);
526:                } catch (Exception e) {
527:                    log.log(Level.WARNING, e.toString(), e);
528:
529:                    throw EJBExceptionWrapper.create(e);
530:                }
531:            }
532:
533:            /**
534:             * Binds the EJB transaction context to the TM transaction context.
535:             */
536:            private void setTransaction(TransactionContext cxt,
537:                    Transaction trans) {
538:                if (cxt != null) {
539:                    Transaction old = cxt.getTransaction();
540:
541:                    if (old != null)
542:                        _transactionMap.remove(old);
543:                } else if (trans != null)
544:                    _transactionMap.remove(trans);
545:
546:                cxt.setTransaction(trans);
547:
548:                if (trans != null)
549:                    _transactionMap.put(trans, cxt);
550:            }
551:
552:            /**
553:             * Create a transaction context.
554:             */
555:            TransactionContext createTransaction() {
556:                TransactionContext trans = _freeTransactions.allocate();
557:
558:                if (trans == null)
559:                    trans = new TransactionContext(this );
560:                trans.init(true);
561:
562:                return trans;
563:            }
564:
565:            /**
566:             * Create a transaction context.
567:             */
568:            TransactionContext createTransactionNoDepth() {
569:                TransactionContext trans = _freeTransactions.allocate();
570:
571:                if (trans == null)
572:                    trans = new TransactionContext(this );
573:                trans.init(false);
574:
575:                return trans;
576:            }
577:
578:            /**
579:             * Creates a transaction from an external xid.
580:             */
581:            public TransactionContext startTransaction(String xid) {
582:                try {
583:                    TransactionContext xa = _foreignTransactionMap.get(xid);
584:
585:                    if (xa != null) {
586:                        resume(xa, xa.getTransaction(), null);
587:                        return xa;
588:                    }
589:
590:                    xa = beginRequiresNew();
591:
592:                    _foreignTransactionMap.put(xid, xa);
593:
594:                    return xa;
595:                } catch (Throwable e) {
596:                    log.log(Level.FINE, e.toString(), e);
597:
598:                    _foreignTransactionMap.remove(xid);
599:
600:                    return null;
601:                }
602:            }
603:
604:            /**
605:             * Creates a transaction from an external xid.
606:             */
607:            public void finishTransaction(String xid) {
608:                try {
609:                    TransactionContext xa = _foreignTransactionMap.get(xid);
610:
611:                    if (xa == null) {
612:                    } else if (xa.isEmpty()) {
613:                        _foreignTransactionMap.remove(xid);
614:                        xa.commit();
615:                    } else {
616:                        suspend();
617:                        //
618:                    }
619:                } catch (Exception e) {
620:                    log.log(Level.FINE, e.toString(), e);
621:                }
622:            }
623:
624:            /**
625:             * Commits a transaction from an external xid.
626:             */
627:            public void commitTransaction(String xid) {
628:                try {
629:                    TransactionContext xa = _foreignTransactionMap.remove(xid);
630:
631:                    if (xa != null) {
632:                        resume(xa, xa.getTransaction(), null);
633:                        xa.commit();
634:                    }
635:                } catch (Throwable e) {
636:                    log.log(Level.FINE, e.toString(), e);
637:                }
638:            }
639:
640:            /**
641:             * Rolls-back a transaction from an external xid.
642:             */
643:            public void rollbackTransaction(String xid) {
644:                try {
645:                    TransactionContext xa = _foreignTransactionMap.remove(xid);
646:
647:                    if (xa != null) {
648:                        resume(xa, xa.getTransaction(), null);
649:                        xa.rollback();
650:                    }
651:                } catch (Throwable e) {
652:                    log.log(Level.FINE, e.toString(), e);
653:                }
654:            }
655:
656:            /**
657:             * Free a transaction context.
658:             */
659:            void freeTransaction(TransactionContext trans) {
660:                _freeTransactions.free(trans);
661:            }
662:
663:            /**
664:             * Closes the container.
665:             */
666:            public void destroy() {
667:                synchronized (this ) {
668:                    if (_isClosed)
669:                        return;
670:
671:                    _isClosed = true;
672:                }
673:
674:                _transactionMap = null;
675:            }
676:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.