Source Code Cross Referenced for ControlImpl.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:         * @(#) ControlImpl.java	1.2 02/01/15
0003:         *
0004:         * JOTM: Java Open Transaction Manager 
0005:         *
0006:         * This module was originally developed by 
0007:         *
0008:         *  - Bull S.A. as part of the JOnAS application server code released in 
0009:         *    July 1999 (www.bull.com)
0010:         * 
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: 
0040:         * 02/01/15 Dean Jennings - ArrayList for resourceList and synchronizationList
0041:         * 02/09/10 Riviere Guillaume (Guillaume.Riviere@inrialpes.fr) - RemoteControl added 
0042:         *
0043:         * --------------------------------------------------------------------------
0044:         * $Id: ControlImpl.java,v 1.30 2005/04/22 17:47:44 tonyortiz Exp $
0045:         * --------------------------------------------------------------------------
0046:         */
0047:        package org.objectweb.jotm;
0048:
0049:        import java.rmi.RemoteException;
0050:        import java.rmi.NoSuchObjectException;
0051:        import java.rmi.ServerException;
0052:
0053:        import javax.rmi.PortableRemoteObject;
0054:
0055:        import java.util.List;
0056:        import java.util.ArrayList;
0057:        import javax.transaction.Status;
0058:        import javax.transaction.TransactionRolledbackException;
0059:        import javax.transaction.xa.Xid;
0060:
0061:        import org.objectweb.carol.util.configuration.ConfigurationRepository;
0062:        import org.objectweb.carol.rmi.exception.RmiUtility;
0063:
0064:        /**
0065:         * Implementation of the object that represents a transaction.
0066:         * This remote object has been created by a TransactionFactory.
0067:         * It extends The RemoteControl Remote Interface 
0068:         *
0069:         * @see	   org.objectweb.jotm.TransactionFactory
0070:         *
0071:         */
0072:        public class ControlImpl extends PortableRemoteObject implements 
0073:                Control, Resource, Coordinator, Terminator,
0074:                RecoveryCoordinator, TimerEventListener {
0075:
0076:            // ===============================================================
0077:            // Private data
0078:            // ===============================================================
0079:            /**
0080:             * @serial
0081:             */
0082:            private List resourceList = new ArrayList();
0083:            /**
0084:             * @serial
0085:             */
0086:            private List synchronizationList = new ArrayList();
0087:            /**
0088:             * @serial
0089:             */
0090:            private int mystatus = Status.STATUS_UNKNOWN;
0091:            /**
0092:             * @serial
0093:             */
0094:            private boolean hasSupCoord = false;
0095:            /**
0096:             * @serial
0097:             */
0098:            private TimerEvent mytimer = null;
0099:            /**
0100:             * @serial
0101:             */
0102:            private Xid xid;
0103:            /**
0104:             * @serial
0105:             */
0106:            private Log mylog;
0107:
0108:            // ---------------------------------------------------------------
0109:            // Constructors
0110:            // ---------------------------------------------------------------
0111:
0112:            /**
0113:             * Constructor for create or recreate
0114:             *
0115:             * @param timeout		Timeout in seconds for this transaction
0116:             * @param x	     	Xid allocated to this transaction
0117:             * @param supco		Superior coordinator (null if create); must be a
0118:             * org.objectweb.jotm.Coordinator or a org.omg.CosTransactions.Coordinator
0119:             */
0120:            ControlImpl(int timeout, Xid x, Object supco)
0121:                    throws RemoteException {
0122:                if (TraceTm.jotm.isDebugEnabled()) {
0123:                    TraceTm.jotm.debug("timeout=" + timeout + ", xid=" + x
0124:                            + ", supco=" + supco);
0125:                }
0126:
0127:                // init object state
0128:                mystatus = Status.STATUS_ACTIVE;
0129:                xid = x;
0130:                hasSupCoord = (supco != null);
0131:
0132:                // XXX In case of sub-coordinator, should we arm a timer for rollback ???
0133:
0134:                mytimer = TimerManager.getInstance().addTimer(this , timeout,
0135:                        new Integer(1), false);
0136:
0137:                // If sub-coord, register resource
0138:                if (supco != null) {
0139:                    try {
0140:                        if (supco instanceof  Coordinator)
0141:                            ((Coordinator) supco).register_resource(this );
0142:                        else
0143:                            // XXX CORBA Cordinator not taken into account
0144:                            // register the control as a CORBA resource in the remote CORBA Coordinator (we use a wraper)
0145:                            //((org.omg.CosTransactions.Coordinator) supco).register_resource(new ControlResourceImpl(this));
0146:                            throw new RemoteException("Not Implemented");
0147:                    } catch (Exception e) {
0148:                        TraceTm.jotm.error(
0149:                                "Cannot register sub-coordinator:\n", e);
0150:                    }
0151:                }
0152:            }
0153:
0154:            // ---------------------------------------------------------------
0155:            // Control Interface 
0156:            // ---------------------------------------------------------------
0157:
0158:            /**
0159:             * Gets the Terminator object for this transaction
0160:             *
0161:             * @return		Terminator for this transaction
0162:             */
0163:            public Terminator get_terminator() throws RemoteException {
0164:
0165:                return this ;
0166:            }
0167:
0168:            /**
0169:             * Gets the Coordinator object for this transaction
0170:             *
0171:             * @return		Coordinator for this transaction
0172:             */
0173:            public Coordinator get_coordinator() throws RemoteException {
0174:                if (TraceTm.jotm.isDebugEnabled()) {
0175:                    TraceTm.jotm.debug("ControlImpl.get_coordinator");
0176:                }
0177:                return this ;
0178:            }
0179:
0180:            // ---------------------------------------------------------------
0181:            // Coordinator Interface 
0182:            // ---------------------------------------------------------------
0183:
0184:            /**
0185:             * Gets the current status of this transaction
0186:             *
0187:             * @return		current transaction status
0188:             */
0189:            public int get_status() throws RemoteException {
0190:                if (TraceTm.jotm.isDebugEnabled()) {
0191:                    TraceTm.jotm.debug("ControlImpl.get_status()");
0192:                }
0193:                return mystatus;
0194:            }
0195:
0196:            /**
0197:             * Tests if the given coordinator represents this transaction
0198:             *
0199:             * @param tc	Coordinator to be compared to this transaction
0200:             * @return			true if it is the same transaction
0201:             */
0202:            public boolean is_same_transaction(Coordinator tc)
0203:                    throws RemoteException {
0204:                if (TraceTm.jotm.isDebugEnabled()) {
0205:                    TraceTm.jotm
0206:                            .debug("ControlImpl.is_same_transaction(Coordinator)");
0207:                }
0208:
0209:                String other = null;
0210:
0211:                try {
0212:                    other = tc.get_transaction_name();
0213:                } catch (Exception e) {
0214:                    if (TraceTm.jotm.isDebugEnabled()) {
0215:                        TraceTm.jotm
0216:                                .error(
0217:                                        "ControlImpl.is_same_transaction() raised exception:\n",
0218:                                        e);
0219:                    }
0220:                    return false;
0221:                }
0222:
0223:                return other.equals(get_transaction_name());
0224:            }
0225:
0226:            /**
0227:             * Registers a Resource object for this transaction
0228:             *
0229:             * @param res		Resource to be registered
0230:             * @return			RecoveryCoordinator used for replay_completion
0231:             */
0232:            public synchronized RecoveryCoordinator register_resource(
0233:                    Resource res) throws RemoteException {
0234:                if (TraceTm.jotm.isDebugEnabled()) {
0235:                    TraceTm.jotm.debug("resource=" + res);
0236:                    TraceTm.jotm.debug("mystatus="
0237:                            + StatusHelper.getStatusName(mystatus));
0238:                }
0239:
0240:                switch (mystatus) {
0241:
0242:                case Status.STATUS_ACTIVE:
0243:                    // Normal case
0244:                    resourceList.add(res);
0245:                    if (TraceTm.jotm.isDebugEnabled()) {
0246:                        TraceTm.jotm.debug("Resource registered");
0247:                    }
0248:                    break;
0249:
0250:                case Status.STATUS_MARKED_ROLLBACK:
0251:                case Status.STATUS_ROLLEDBACK:
0252:                case Status.STATUS_ROLLING_BACK:
0253:                    TraceTm.jotm
0254:                            .error("ControlImpl.register_resource(): Transaction Rolled back");
0255:                    TraceTm.jotm.error("mystatus= "
0256:                            + StatusHelper.getStatusName(mystatus));
0257:                    throw new TransactionRolledbackException();
0258:
0259:                default:
0260:                    TraceTm.jotm
0261:                            .error("ControlImpl.register_resource(): Transaction Inactive");
0262:                    TraceTm.jotm.error("mystatus= "
0263:                            + StatusHelper.getStatusName(mystatus));
0264:                    throw new InactiveException(
0265:                            "Cannot register resource, status "
0266:                                    + StatusHelper.getStatusName(mystatus));
0267:                }
0268:                return this ;
0269:            }
0270:
0271:            /**
0272:             * Registers a Synchronization object for this transaction
0273:             *
0274:             * @param sync		RemoteSynchro to be registered
0275:             */
0276:            public synchronized void register_synchronization(RemoteSynchro sync)
0277:                    throws RemoteException {
0278:                if (TraceTm.jotm.isDebugEnabled()) {
0279:                    TraceTm.jotm.debug("sync=" + sync);
0280:                    TraceTm.jotm.debug("mystatus="
0281:                            + StatusHelper.getStatusName(mystatus));
0282:                }
0283:
0284:                switch (mystatus) {
0285:
0286:                case Status.STATUS_ACTIVE:
0287:                    // Normal case
0288:                    synchronizationList.add(sync);
0289:                    if (TraceTm.jotm.isDebugEnabled()) {
0290:                        TraceTm.jotm
0291:                                .debug("ControlImpl.register_synchronization(): RemoteSynchro registered");
0292:                    }
0293:                    break;
0294:
0295:                case Status.STATUS_MARKED_ROLLBACK:
0296:                case Status.STATUS_ROLLEDBACK:
0297:                case Status.STATUS_ROLLING_BACK:
0298:                    TraceTm.jotm
0299:                            .error("ControlImpl.register_synchronization(): Transaction Rolled back");
0300:                    TraceTm.jotm.error("mystatus= "
0301:                            + StatusHelper.getStatusName(mystatus));
0302:                    throw new TransactionRolledbackException();
0303:
0304:                default:
0305:                    TraceTm.jotm
0306:                            .error("ControlImpl.register_synchronization(): Transaction Inactive");
0307:                    TraceTm.jotm.error("mystatus= "
0308:                            + StatusHelper.getStatusName(mystatus));
0309:                    throw new InactiveException(
0310:                            "Cannot register synchronization, status "
0311:                                    + StatusHelper.getStatusName(mystatus));
0312:                }
0313:            }
0314:
0315:            /**
0316:             * Asks to rollback the transaction
0317:             *
0318:             */
0319:            public synchronized void rollback_only() throws RemoteException {
0320:                if (TraceTm.jotm.isDebugEnabled()) {
0321:                    TraceTm.jotm.debug("mystatus="
0322:                            + StatusHelper.getStatusName(mystatus));
0323:                }
0324:
0325:                switch (mystatus) {
0326:
0327:                case Status.STATUS_MARKED_ROLLBACK:
0328:                    // nothing to do: Already marked rolledback.
0329:                    if (TraceTm.jotm.isDebugEnabled()) {
0330:                        TraceTm.jotm
0331:                                .debug("ControlImpl.rollback_only(): Already marked rolledback");
0332:                    }
0333:                    break;
0334:
0335:                case Status.STATUS_ACTIVE:
0336:                    // case Status.STATUS_COMMITTING :
0337:                    mystatus = Status.STATUS_MARKED_ROLLBACK;
0338:                    if (TraceTm.jotm.isDebugEnabled()) {
0339:                        TraceTm.jotm
0340:                                .debug("ControlImpl.rollback_only(): Marked rollback");
0341:                    }
0342:                    break;
0343:
0344:                default:
0345:                    // already prepared
0346:                    TraceTm.jotm.error("ControlImpl.rollback_only(): Inactive");
0347:                    TraceTm.jotm.error("mystatus= "
0348:                            + StatusHelper.getStatusName(mystatus));
0349:                    throw new InactiveException(
0350:                            "Cannot rollback transaction, status "
0351:                                    + StatusHelper.getStatusName(mystatus));
0352:                }
0353:            }
0354:
0355:            /**
0356:             * Gets a String that represents the transaction name.
0357:             * Only the Format Id and the Global Id are used to build it :
0358:             * The Branch Qualifier is not used.
0359:             *
0360:             * @return			Transaction Name
0361:             */
0362:            public String get_transaction_name() throws RemoteException {
0363:                if (TraceTm.jotm.isDebugEnabled()) {
0364:                    TraceTm.jotm.debug("ControlImpl.get_transaction_name()");
0365:                }
0366:
0367:                return xid.toString();
0368:            }
0369:
0370:            // ---------------------------------------------------------------
0371:            // Terminator Interface 
0372:            // ---------------------------------------------------------------
0373:
0374:            /**
0375:             * Commits this transaction
0376:             *
0377:             * @param report_heuristics want to report heuristics if any
0378:             * 
0379:             * @exception TransactionRolledbackException the transaction has been rolled back
0380:             * @exception HeuristicMixed Resources have rolled back
0381:             * @exception HeuristicHazard Resources may have rolled back
0382:             */
0383:            public synchronized void commit(boolean report_heuristics)
0384:                    throws RemoteException {
0385:                if (TraceTm.jotm.isDebugEnabled()) {
0386:                    TraceTm.jotm
0387:                            .debug("report_heuristics=" + report_heuristics);
0388:                    TraceTm.jotm.debug("mystatus="
0389:                            + StatusHelper.getStatusName(mystatus));
0390:                }
0391:
0392:                String protocol = ConfigurationRepository
0393:                        .getCurrentConfiguration().getProtocol().getName();
0394:
0395:                // Stops the Timer.
0396:                if (mytimer != null) {
0397:                    mytimer.stop();
0398:                }
0399:
0400:                // Checks status
0401:                switch (mystatus) {
0402:
0403:                case Status.STATUS_ACTIVE:
0404:                    // normal case
0405:                    break;
0406:
0407:                case Status.STATUS_COMMITTED:
0408:                    TraceTm.jotm
0409:                            .error("ControlImpl.commit(boolean): already done");
0410:                    return;
0411:
0412:                case Status.STATUS_ROLLEDBACK:
0413:                    TraceTm.jotm
0414:                            .error("ControlImpl.commit(boolean): already rolled back");
0415:                    // We should be here in case of timeout expired.
0416:                    // In this case, completed() was not called.
0417:                    completed(true);
0418:
0419:                    if (protocol == null || !(protocol.equals("iiop"))) {
0420:                        throw new TransactionRolledbackException();
0421:                    }
0422:
0423:                    RmiUtility
0424:                            .rethrowRmiException(new TransactionRolledbackException());
0425:
0426:                case Status.STATUS_MARKED_ROLLBACK:
0427:                    // Synchronization objects
0428:                    int errors = do_before_completion();
0429:
0430:                    if (errors > 0) {
0431:                        TraceTm.jotm
0432:                                .info("ControlImpl.commit(boolean): before completion error at rollback");
0433:                    }
0434:
0435:                    do_rollback(report_heuristics);
0436:                    completed(true);
0437:
0438:                    if (protocol == null || !(protocol.equals("iiop"))) {
0439:                        throw new TransactionRolledbackException();
0440:                    }
0441:
0442:                    RmiUtility
0443:                            .rethrowRmiException(new TransactionRolledbackException());
0444:
0445:                default:
0446:                    TraceTm.jotm
0447:                            .error("ControlImpl.commit(boolean): bad status");
0448:                    TraceTm.jotm.error("mystatus= "
0449:                            + StatusHelper.getStatusName(mystatus));
0450:
0451:                    if (protocol == null || !(protocol.equals("iiop"))) {
0452:                        throw new HeuristicMixed();
0453:                    }
0454:
0455:                    RmiUtility.rethrowRmiException(new HeuristicMixed());
0456:                }
0457:
0458:                // Only one resource -> one phase commit.
0459:                // If Resource raises an heuristic, forward it to the client.
0460:                if (resourceList.size() == 1) {
0461:                    TraceTm.jotm.debug("1 resource");
0462:
0463:                    // Synchronization objects
0464:                    int errors = do_before_completion();
0465:
0466:                    if (errors > 0) {
0467:                        TraceTm.jotm
0468:                                .info("before completion error -> rollback");
0469:                        do_rollback(report_heuristics);
0470:                        completed(true);
0471:
0472:                        if (protocol == null || !(protocol.equals("iiop"))) {
0473:                            throw new TransactionRolledbackException();
0474:                        }
0475:
0476:                        RmiUtility
0477:                                .rethrowRmiException(new TransactionRolledbackException());
0478:                    }
0479:
0480:                    mystatus = Status.STATUS_COMMITTING;
0481:
0482:                    try {
0483:                        Resource res = (Resource) resourceList.get(0);
0484:                        res.commit_one_phase();
0485:                        mystatus = Status.STATUS_COMMITTED;
0486:                    } catch (TransactionRolledbackException e) {
0487:                        TraceTm.jotm
0488:                                .info("commit_one_phase = TransactionRolledbackException");
0489:                        mystatus = Status.STATUS_ROLLEDBACK;
0490:                    } catch (HeuristicHazard e) {
0491:                        TraceTm.jotm
0492:                                .info("commit_one_phase = HeuristicException");
0493:                        mystatus = Status.STATUS_UNKNOWN;
0494:                    } catch (NoSuchObjectException e) {
0495:                        // nothing done: can rollback transaction
0496:                        TraceTm.jotm
0497:                                .info("commit_one_phase = NoSuchObjectException");
0498:                        mystatus = Status.STATUS_ROLLEDBACK;
0499:                    } catch (ServerException e) { // with RMI, may encapsulate TransactionRolledbackException
0500:                        TraceTm.jotm
0501:                                .info("commit_one_phase = ServerException: "
0502:                                        + e);
0503:                        mystatus = Status.STATUS_ROLLEDBACK;
0504:                    } catch (Exception e) {
0505:                        TraceTm.jotm.error(
0506:                                "commit_one_phase = Unexpected exception: ", e);
0507:                        mystatus = Status.STATUS_UNKNOWN;
0508:                    }
0509:
0510:                    // Synchronization objects
0511:                    do_after_completion();
0512:
0513:                    // Possibly report heuristics to the caller
0514:                    switch (mystatus) {
0515:                    case Status.STATUS_COMMITTED:
0516:                        completed(true);
0517:                        break;
0518:                    case Status.STATUS_ROLLEDBACK:
0519:                        completed(true);
0520:
0521:                        if (protocol == null || !(protocol.equals("iiop"))) {
0522:                            throw new TransactionRolledbackException();
0523:                        }
0524:
0525:                        RmiUtility
0526:                                .rethrowRmiException(new TransactionRolledbackException());
0527:                    case Status.STATUS_UNKNOWN:
0528:                        completed(false);
0529:
0530:                        if (report_heuristics) {
0531:                            if (protocol == null || !(protocol.equals("iiop"))) {
0532:                                throw new HeuristicHazard();
0533:                            }
0534:
0535:                            RmiUtility
0536:                                    .rethrowRmiException(new HeuristicHazard());
0537:                        }
0538:                    }
0539:                    return;
0540:                }
0541:
0542:                // 2PC - phase 1
0543:                int v = do_prepare(report_heuristics);
0544:
0545:                if (TraceTm.jotm.isDebugEnabled()) {
0546:                    TraceTm.jotm.debug("Vote = " + v);
0547:                }
0548:
0549:                // Depending on vote, commits or rollbacks transaction
0550:                switch (v) {
0551:                case Resource.VOTE_COMMIT:
0552:                    if (TraceTm.jotm.isDebugEnabled()) {
0553:                        TraceTm.jotm
0554:                                .debug("ControlImpl.commit(boolean): committing Tx");
0555:                    }
0556:                    break;
0557:                case Resource.VOTE_ROLLBACK:
0558:                    if (TraceTm.jotm.isDebugEnabled()) {
0559:                        TraceTm.jotm
0560:                                .debug("ControlImpl.commit(boolean): rolling back Tx");
0561:                    }
0562:                    do_rollback(report_heuristics);
0563:                    completed(true);
0564:
0565:                    if (protocol == null || !(protocol.equals("iiop"))) {
0566:                        throw new TransactionRolledbackException();
0567:                    }
0568:
0569:                    RmiUtility
0570:                            .rethrowRmiException(new TransactionRolledbackException());
0571:                case Resource.VOTE_READONLY:
0572:                    // No commit phase.
0573:                    if (TraceTm.jotm.isDebugEnabled()) {
0574:                        TraceTm.jotm
0575:                                .debug("ControlImpl.commit(boolean): readonly resources");
0576:                    }
0577:                    mystatus = Status.STATUS_COMMITTED;
0578:                    completed(true);
0579:                    return;
0580:                }
0581:
0582:                // Prepare was OK: Decision to commit.
0583:                mylog.flushLog(Log.DECISION_TO_COMMIT);
0584:
0585:                // 2PC - phase 2
0586:                if (do_commit(report_heuristics) == 0) {
0587:                    completed(true);
0588:                } else {
0589:                    completed(false);
0590:                }
0591:            }
0592:
0593:            // ---------------------------------------------------------------
0594:            // Resource or Terminator Interface 
0595:            // rollback() has the same signature in Terminator and Resource!
0596:            // ---------------------------------------------------------------
0597:
0598:            /**
0599:             * Rolls back this transaction branch. Can be a sub-coordinator or
0600:             * a normal coordinator.
0601:             *
0602:             */
0603:            public synchronized void rollback() throws RemoteException {
0604:                if (TraceTm.jotm.isDebugEnabled()) {
0605:                    TraceTm.jotm.debug("mystatus="
0606:                            + StatusHelper.getStatusName(mystatus));
0607:                }
0608:
0609:                String protocol = ConfigurationRepository
0610:                        .getCurrentConfiguration().getProtocol().getName();
0611:
0612:                // Stops the Timer. 
0613:                if (mytimer != null) {
0614:                    mytimer.stop();
0615:                }
0616:
0617:                // Checks status
0618:                switch (mystatus) {
0619:
0620:                case Status.STATUS_ACTIVE:
0621:                case Status.STATUS_MARKED_ROLLBACK:
0622:                    // normal case
0623:                    break;
0624:
0625:                case Status.STATUS_ROLLEDBACK:
0626:                    TraceTm.jotm
0627:                            .error("ControlImpl.rollback(): already rolled back");
0628:                    TraceTm.jotm.error("mystatus= "
0629:                            + StatusHelper.getStatusName(mystatus));
0630:                    return;
0631:
0632:                default:
0633:                    TraceTm.jotm
0634:                            .error("ControlImpl.rollback(): rollback: bad status");
0635:                    TraceTm.jotm.error("mystatus= "
0636:                            + StatusHelper.getStatusName(mystatus));
0637:                    completed(false);
0638:
0639:                    if (protocol == null || !(protocol.equals("iiop"))) {
0640:                        throw new HeuristicMixed("rollback: bad status");
0641:                    }
0642:
0643:                    RmiUtility
0644:                            .rethrowRmiException(new TransactionRolledbackException());
0645:                }
0646:
0647:                // Superior coordinator.
0648:                if (!hasSupCoord) {
0649:                    // Synchronization objects
0650:                    int errors = do_before_completion();
0651:                    if (errors > 0) {
0652:                        TraceTm.jotm
0653:                                .info("ControlImpl.rollback(): before completion error at rollback");
0654:                    }
0655:                }
0656:
0657:                // rollback Tx
0658:                try {
0659:                    do_rollback(false);
0660:                } catch (Exception e) {
0661:                    TraceTm.jotm
0662:                            .error(
0663:                                    "ControlImpl.rollback(): rollback raised exception ",
0664:                                    e);
0665:                }
0666:                completed(true);
0667:            }
0668:
0669:            // ---------------------------------------------------------------
0670:            // Resource Interface (for sub-coordinators)
0671:            // ---------------------------------------------------------------
0672:
0673:            /**
0674:             * Sub-coordinator has received prepare from its superior.
0675:             * It must more or less do the same things that the phase 1 of the 2PC.
0676:             *
0677:             * @return		Vote : commit, roollback or read-only.
0678:             */
0679:            public synchronized int prepare() throws RemoteException {
0680:                if (TraceTm.jotm.isDebugEnabled()) {
0681:                    TraceTm.jotm.debug("mystatus="
0682:                            + StatusHelper.getStatusName(mystatus));
0683:                }
0684:
0685:                // Stops the Timer. 
0686:                if (mytimer != null) {
0687:                    mytimer.stop();
0688:                }
0689:
0690:                // Checks status
0691:                switch (mystatus) {
0692:
0693:                case Status.STATUS_ACTIVE:
0694:                    // normal case
0695:                    break;
0696:
0697:                case Status.STATUS_COMMITTED:
0698:                    // Should not occur ?
0699:                    TraceTm.jotm
0700:                            .error("ControlImpl.prepare(): transaction already commited");
0701:                    TraceTm.jotm.error("mystatus= "
0702:                            + StatusHelper.getStatusName(mystatus));
0703:                    return Resource.VOTE_COMMIT;
0704:
0705:                case Status.STATUS_ROLLEDBACK:
0706:                    // Should not occur ?
0707:                    TraceTm.jotm
0708:                            .error("ControlImpl.prepare(): transaction already rolled back");
0709:                    TraceTm.jotm.error("mystatus= "
0710:                            + StatusHelper.getStatusName(mystatus));
0711:                    return Resource.VOTE_ROLLBACK;
0712:
0713:                case Status.STATUS_MARKED_ROLLBACK:
0714:                    do_rollback(false);
0715:                    completed(true);
0716:                    return Resource.VOTE_ROLLBACK;
0717:
0718:                default:
0719:                    // Don't know what to do here...
0720:                    TraceTm.jotm.error("ControlImpl.prepare(): bad status");
0721:                    TraceTm.jotm.error("mystatus= "
0722:                            + StatusHelper.getStatusName(mystatus));
0723:                    completed(false);
0724:                    return Resource.VOTE_ROLLBACK;
0725:                }
0726:
0727:                int ret = do_prepare(false);
0728:
0729:                switch (ret) {
0730:                case Resource.VOTE_COMMIT:
0731:                    if (TraceTm.jotm.isDebugEnabled()) {
0732:                        TraceTm.jotm
0733:                                .debug("ControlImpl.prepare(): vote commit");
0734:                    }
0735:                    break;
0736:                case Resource.VOTE_ROLLBACK:
0737:                    if (TraceTm.jotm.isDebugEnabled()) {
0738:                        TraceTm.jotm
0739:                                .debug("ControlImpl.prepare(): vote rollback");
0740:                    }
0741:                    do_rollback(false);
0742:                    completed(true);
0743:                    return ret;
0744:                case Resource.VOTE_READONLY:
0745:                    if (TraceTm.jotm.isDebugEnabled()) {
0746:                        TraceTm.jotm
0747:                                .debug("ControlImpl.prepare(): vote readonly");
0748:                    }
0749:                    mystatus = Status.STATUS_COMMITTED;
0750:                    completed(true);
0751:                    return ret;
0752:                }
0753:
0754:                // Flush log + recovery coordinator
0755:                // TODO
0756:
0757:                return ret;
0758:            }
0759:
0760:            /**
0761:             * Sub-coordinator received commit from its superior.
0762:             * It must more or less do the same things that the phase 2 of the 2PC.
0763:             */
0764:            public synchronized void commit() throws RemoteException {
0765:                if (TraceTm.jotm.isDebugEnabled()) {
0766:                    TraceTm.jotm.debug("mystatus="
0767:                            + StatusHelper.getStatusName(mystatus));
0768:                }
0769:
0770:                // check status
0771:                switch (mystatus) {
0772:                case Status.STATUS_PREPARED:
0773:                    // normal case
0774:                    break;
0775:                default:
0776:                    // Don't know what to do here...
0777:                    TraceTm.jotm
0778:                            .error("ControlImpl.commit(): commit: bad status");
0779:                    TraceTm.jotm.error("mystatus= "
0780:                            + StatusHelper.getStatusName(mystatus));
0781:                    completed(false);
0782:                    return;
0783:                }
0784:
0785:                // send commit to resources
0786:                if (do_commit(true) == 0) {
0787:                    completed(true);
0788:                } else {
0789:                    completed(false);
0790:                }
0791:            }
0792:
0793:            /**
0794:             * Sub-coordinator received commit_one_phase from its superior.
0795:             * It is more or less a Terminator.commit().
0796:             */
0797:            public void commit_one_phase() throws RemoteException {
0798:                if (TraceTm.jotm.isDebugEnabled()) {
0799:                    TraceTm.jotm.debug("ControlImpl.commit_one_phase()");
0800:                }
0801:
0802:                // Just call Terminator.commit
0803:                commit(true);
0804:            }
0805:
0806:            /**
0807:             * forget transaction
0808:             *
0809:             */
0810:            public synchronized void forget() throws RemoteException {
0811:                if (TraceTm.jotm.isDebugEnabled()) {
0812:                    TraceTm.jotm.debug("ControlImpl.forget()");
0813:                }
0814:
0815:                completed(true);
0816:            }
0817:
0818:            // ---------------------------------------------------------------
0819:            // RecoveryCoordinator Interface 
0820:            // ---------------------------------------------------------------
0821:
0822:            /**
0823:             * Asks the status of this transaction, after recovery of a Resource
0824:             *
0825:             * @param res		Resource recovering
0826:             */
0827:            public int replay_completion(Resource res) throws RemoteException {
0828:                if (TraceTm.jotm.isDebugEnabled()) {
0829:                    TraceTm.jotm.debug("res=" + res);
0830:                }
0831:                return mystatus;
0832:            }
0833:
0834:            // ===============================================================
0835:            // TimerEventListener implementation
0836:            // ===============================================================
0837:
0838:            /**
0839:             * The transaction timeout has expired
0840:             * Do not synchronize this method to avoid deadlocks!
0841:             */
0842:            public void timeoutExpired(Object arg) {
0843:                if (TraceTm.jotm.isDebugEnabled()) {
0844:                    TraceTm.jotm.debug("arg=" + arg);
0845:                }
0846:
0847:                int argvalue = ((Integer) arg).intValue();
0848:
0849:                switch (argvalue) {
0850:                case 1:
0851:                    if (TraceTm.jotm.isDebugEnabled()) {
0852:                        TraceTm.jotm
0853:                                .debug("ControlImpl.timeoutExpired(Object): timeout expired");
0854:                    }
0855:
0856:                    try {
0857:                        do_rollback(false);
0858:                    } catch (Exception e) {
0859:                        TraceTm.jotm
0860:                                .error(
0861:                                        "ControlImpl.timeoutExpired(Object): rollback raised exception ",
0862:                                        e);
0863:                    }
0864:                    break;
0865:                case 2:
0866:                    if (TraceTm.jotm.isDebugEnabled()) {
0867:                        TraceTm.jotm
0868:                                .debug("ControlImpl.timeoutExpired(Object): removing ControlImpl");
0869:                    }
0870:                    explicit_destroy();
0871:                    break;
0872:                default:
0873:                    TraceTm.jotm
0874:                            .error("ControlImpl.timeoutExpired(Object): timeoutExpired bad value="
0875:                                    + argvalue);
0876:                    break;
0877:                }
0878:            }
0879:
0880:            // ===============================================================
0881:            // Private methods
0882:            // ===============================================================
0883:
0884:            /**
0885:             * timeout expired on this transaction.
0886:             * This method is not private, because it's used by Timers
0887:             */
0888:            void ding() {
0889:                if (TraceTm.jotm.isDebugEnabled()) {
0890:                    TraceTm.jotm.debug("");
0891:                }
0892:            }
0893:
0894:            /**
0895:             * Phase 1 of the 2-Phase-Commit:
0896:             * Sends prepare to each registered resource
0897:             * This internal routine should be used either for prepare on sub-coordinator
0898:             *  or for commit on Terminator.
0899:             *
0900:             * @return			global vote
0901:             */
0902:            private int do_prepare(boolean report_heuristics) {
0903:                if (TraceTm.jotm.isDebugEnabled()) {
0904:                    TraceTm.jotm
0905:                            .debug("report_heuristics=" + report_heuristics);
0906:                }
0907:
0908:                int errors = 0;
0909:                int ret = Resource.VOTE_READONLY;
0910:
0911:                // Synchronization objects
0912:                errors = do_before_completion();
0913:
0914:                if (errors > 0) {
0915:                    if (TraceTm.jotm.isDebugEnabled()) {
0916:                        TraceTm.jotm
0917:                                .debug("before_completion failed -> rollback");
0918:                    }
0919:                    return Resource.VOTE_ROLLBACK;
0920:                }
0921:
0922:                // No resource -> just forget transaction.
0923:                if (resourceList.size() == 0) {
0924:                    TraceTm.jotm.error("commit: no resource");
0925:                    mystatus = Status.STATUS_COMMITTED;
0926:                    do_after_completion();
0927:                    completed(true);
0928:                    return ret;
0929:                }
0930:
0931:                // Creates a log for that transaction, where we will add all the
0932:                // resources that replied VOTE_COMMIT to prepare.
0933:                // Do not flush the log on disk before decision to commit.
0934:                mylog = new Log();
0935:
0936:                // Sends prepare to each resource.
0937:                // In case of prepare on sub-coord. we may have only 1 resource.
0938:                // In case of phase 1 of the 2PC, we have several resources, because
0939:                // the case of 1 resource is treated with commit_one_phase (optimization)
0940:                mystatus = Status.STATUS_PREPARING;
0941:
0942:                for (int i = 0; i < resourceList.size(); i++) {
0943:                    Resource res = (Resource) resourceList.get(i);
0944:
0945:                    if (errors > 0) {
0946:                        if (TraceTm.jotm.isWarnEnabled()) {
0947:                            TraceTm.jotm
0948:                                    .warn("Vote stopped: at least one resource has voted rollback.");
0949:                        }
0950:                        break;
0951:                    } else {
0952:                        // No error yet: Send prepare to the resource.
0953:                        try {
0954:                            if (TraceTm.jotm.isDebugEnabled()) {
0955:                                TraceTm.jotm.debug("send prepare to resource");
0956:                            }
0957:
0958:                            switch (res.prepare()) {
0959:                            case Resource.VOTE_COMMIT:
0960:                                // Log resource
0961:                                mylog.addResource(res);
0962:                                TraceTm.jotm
0963:                                        .info("Resource replied commit to prepare");
0964:                                ret = Resource.VOTE_COMMIT;
0965:                                break;
0966:                            case Resource.VOTE_ROLLBACK:
0967:                                TraceTm.jotm
0968:                                        .info("Resource replied rollback to prepare");
0969:                                ret = Resource.VOTE_ROLLBACK;
0970:                                errors++;
0971:                                break;
0972:                            case Resource.VOTE_READONLY:
0973:                                if (TraceTm.jotm.isDebugEnabled()) {
0974:                                    TraceTm.jotm
0975:                                            .debug("Resource replied readonly to prepare");
0976:                                }
0977:                                break;
0978:                            }
0979:                        } catch (HeuristicHazard e) { // Subcoordinator only
0980:                            TraceTm.jotm.error("HeuristicHazard on prepare");
0981:                            ret = Resource.VOTE_ROLLBACK;
0982:                            errors++;
0983:                        } catch (HeuristicMixed e) { // Subcoordinator only
0984:                            TraceTm.jotm.error("HeuristicMixed on prepare");
0985:                            ret = Resource.VOTE_ROLLBACK;
0986:                            errors++;
0987:                        } catch (Exception e) {
0988:                            TraceTm.jotm.error("exception on prepare: ", e);
0989:                            ret = Resource.VOTE_ROLLBACK;
0990:                            errors++;
0991:                        }
0992:                    }
0993:                }
0994:
0995:                if (ret == Resource.VOTE_READONLY) {
0996:                    if (TraceTm.jotm.isDebugEnabled()) {
0997:                        TraceTm.jotm.debug("All resources returned Readonly");
0998:                    }
0999:                    mystatus = Status.STATUS_COMMITTED;
1000:                    // Synchronization objects
1001:                    do_after_completion();
1002:                }
1003:                if (ret == Resource.VOTE_COMMIT) {
1004:                    mystatus = Status.STATUS_PREPARED;
1005:                }
1006:
1007:                if (TraceTm.jotm.isDebugEnabled()) {
1008:                    if (TraceTm.jotm.isDebugEnabled()) {
1009:                        TraceTm.jotm.debug("Vote = " + ret);
1010:                    }
1011:                }
1012:                return ret;
1013:            }
1014:
1015:            /**
1016:             * Phase 2 of the 2-Phase-Commit:
1017:             * Sends commit to each registered resource
1018:             * This internal routine should be used either for commit on sub-coordinator
1019:             *  or for commit on Terminator.
1020:             *
1021:             * @return		0 if commit OK.
1022:             */
1023:            private int do_commit(boolean report_heuristics)
1024:                    throws TransactionRolledbackException, HeuristicMixed,
1025:                    HeuristicHazard, HeuristicRollback {
1026:
1027:                if (TraceTm.jotm.isDebugEnabled()) {
1028:                    TraceTm.jotm
1029:                            .debug("report_heuristics=" + report_heuristics);
1030:                }
1031:
1032:                // First check that a log is initialized
1033:                if (mylog == null) {
1034:                    TraceTm.jotm.error("no log");
1035:                    return -1;
1036:                }
1037:
1038:                // Status Transaction = committing
1039:                mystatus = Status.STATUS_COMMITTING;
1040:
1041:                // Sends commit to each resource "prepared".
1042:                int commitnb = 0;
1043:                int heuristicnb = 0;
1044:                int errors = 0;
1045:                int heuristicstate = 0;
1046:
1047:                for (int i = 0; i < mylog.resourceLogged.size(); i++) {
1048:                    ResourceInfo resinfo = (ResourceInfo) mylog.resourceLogged
1049:                            .elementAt(i);
1050:
1051:                    if (resinfo.mystate != ResourceInfo.PREPARED) {
1052:                        TraceTm.jotm.info("resource not prepared");
1053:                        continue;
1054:                    }
1055:
1056:                    // aborts transaction if error and no resource committed yet
1057:                    if (commitnb == 0 && errors > 0) {
1058:                        try {
1059:                            TraceTm.jotm.info("Send rollback to resource");
1060:                            resinfo.getResource().rollback();
1061:                            resinfo.mystate = ResourceInfo.ROLLEDBACK;
1062:                        } catch (HeuristicCommit e) {
1063:                            TraceTm.jotm.error("Heuristic commit");
1064:                            resinfo.mystate = ResourceInfo.HEURISTIC_COMMIT;
1065:                            heuristicstate = ResourceInfo.HEURISTIC_COMMIT;
1066:                            commitnb++;
1067:                            heuristicnb++;
1068:                        } catch (Exception e) {
1069:                            TraceTm.jotm.error("exception on rollback: ", e);
1070:                        }
1071:                        continue;
1072:                    }
1073:
1074:                    // commits resource
1075:
1076:                    try {
1077:                        TraceTm.jotm.debug("Send commit to resource");
1078:                        resinfo.getResource().commit();
1079:                        resinfo.mystate = ResourceInfo.COMMITTED;
1080:                        commitnb++;
1081:                    } catch (HeuristicRollback e) {
1082:                        TraceTm.jotm.error("Heuristic Rollback");
1083:                        resinfo.mystate = ResourceInfo.HEURISTIC_ROLLBACK;
1084:                        heuristicstate = ResourceInfo.HEURISTIC_ROLLBACK;
1085:                        errors++;
1086:                        if (commitnb > 0)
1087:                            heuristicnb++;
1088:                    } catch (HeuristicMixed e) {
1089:                        TraceTm.jotm.error("Heuristic Mixed");
1090:                        resinfo.mystate = ResourceInfo.HEURISTIC_MIXED;
1091:                        heuristicstate = ResourceInfo.HEURISTIC_MIXED;
1092:                        errors++;
1093:                        commitnb++;
1094:                        heuristicnb++;
1095:                    } catch (HeuristicHazard e) {
1096:                        TraceTm.jotm.error("Heuristic Hazard");
1097:                        resinfo.mystate = ResourceInfo.HEURISTIC_HAZARD;
1098:                        heuristicstate = ResourceInfo.HEURISTIC_HAZARD;
1099:                        errors++;
1100:                        commitnb++;
1101:                        heuristicnb++;
1102:                    } catch (NotPreparedException e) {
1103:                        TraceTm.jotm.error("Resource Not Prepared");
1104:                        resinfo.mystate = ResourceInfo.REGISTERED;
1105:                        errors++;
1106:                    } catch (NoSuchObjectException e) {
1107:                        TraceTm.jotm.error("invalid objref - assume committed");
1108:                        resinfo.mystate = ResourceInfo.COMMITTED;
1109:                        commitnb++;
1110:                    } catch (Exception e) {
1111:                        TraceTm.jotm.error("exception on commit: ", e);
1112:                        errors++;
1113:                    }
1114:                }
1115:
1116:                if (errors == 0) {
1117:                    // Everything's fine.
1118:                    if (TraceTm.jotm.isDebugEnabled()) {
1119:                        TraceTm.jotm.debug("transaction committed");
1120:                    }
1121:
1122:                    mystatus = Status.STATUS_COMMITTED;
1123:                    mylog.forgetLog();
1124:                    // Synchronization Objects
1125:                    do_after_completion();
1126:                    return 0;
1127:                }
1128:
1129:                if (heuristicnb == 0) {
1130:                    // Transaction has been eventually rolled back
1131:                    TraceTm.jotm.info("transaction rolled back");
1132:                    mystatus = Status.STATUS_ROLLEDBACK;
1133:                    mylog.forgetLog();
1134:                    // Synchronization Objects
1135:                    do_after_completion();
1136:                    throw new TransactionRolledbackException();
1137:                }
1138:
1139:                // Heuristics must be logged
1140:                TraceTm.jotm.info("Heuristics must be logged");
1141:                mystatus = Status.STATUS_UNKNOWN;
1142:                mylog.updateLog();
1143:
1144:                // Synchronization Objects
1145:                do_after_completion();
1146:
1147:                if (report_heuristics) {
1148:                    switch (heuristicstate) {
1149:                    case (ResourceInfo.HEURISTIC_ROLLBACK): {
1150:                        throw new HeuristicRollback();
1151:                    }
1152:                    case (ResourceInfo.HEURISTIC_MIXED): {
1153:                        throw new HeuristicMixed();
1154:                    }
1155:                    case (ResourceInfo.HEURISTIC_HAZARD): {
1156:                        throw new HeuristicHazard();
1157:                    }
1158:                    }
1159:                }
1160:
1161:                return -1;
1162:            }
1163:
1164:            /**
1165:             * Rollbacks the transaction
1166:             * This internal routine should be used either for rollback on sub-coordinator
1167:             * or for commit on Terminator when prepare returned a vote RollBack.
1168:             */
1169:            private void do_rollback(boolean report_heuristics)
1170:                    throws HeuristicMixed {
1171:                if (TraceTm.jotm.isDebugEnabled()) {
1172:                    TraceTm.jotm
1173:                            .debug("report_heuristics=" + report_heuristics);
1174:                }
1175:
1176:                mystatus = Status.STATUS_ROLLEDBACK;
1177:
1178:                // Rollback resources
1179:                int commitnb = 0;
1180:
1181:                for (int i = 0; i < resourceList.size(); i++) {
1182:                    Resource res = (Resource) resourceList.get(i);
1183:                    try {
1184:                        if (TraceTm.jotm.isDebugEnabled()) {
1185:                            TraceTm.jotm.debug("Send rollback to Resource");
1186:                        }
1187:                        res.rollback();
1188:                    } catch (HeuristicCommit e) {
1189:                        TraceTm.jotm.error("Rollback raised HeuristicCommit");
1190:                        commitnb++;
1191:                    } catch (Exception e) {
1192:                        TraceTm.jotm.error("Cannot rollback resource: ", e);
1193:                    }
1194:                }
1195:
1196:                // Synchronization objects
1197:                do_after_completion();
1198:
1199:                if (commitnb > 0 && report_heuristics) {
1200:                    // May be should throw HeuristicCommit instead
1201:                    throw new HeuristicMixed();
1202:                }
1203:            }
1204:
1205:            /**
1206:             * Destroys transaction object.
1207:             */
1208:            private void explicit_destroy() {
1209:                if (TraceTm.jotm.isDebugEnabled()) {
1210:                    TraceTm.jotm.debug("");
1211:                }
1212:
1213:                // unexportObject explicitly
1214:                try {
1215:                    unexportObject(this );
1216:                } catch (Exception e) {
1217:                }
1218:            }
1219:
1220:            /**
1221:             * Delay destroy of the ControlImpl object.
1222:             * We must keep alive this object a little while for recovery reasons, 
1223:             * and also in case of Jeremie because we may propagate a reference to 
1224:             * this object inside the propagation context.
1225:             */
1226:            private void completed(boolean removeit) {
1227:                if (TraceTm.jotm.isDebugEnabled()) {
1228:                    TraceTm.jotm.debug("removeit=" + removeit);
1229:                }
1230:
1231:                if (mytimer != null) {
1232:                    if (removeit) {
1233:                        // Convert the timer to make a delayed removal of this object
1234:                        mytimer.change(60, new Integer(2));
1235:                    } else {
1236:                        // In case of heuristic, must keep ControlImpl.
1237:                        // No more timer is needed.
1238:                        mytimer.unset();
1239:                        mytimer = null;
1240:                    }
1241:                }
1242:            }
1243:
1244:            /**
1245:             * Sends before_completion to the registered synchronizations
1246:             *
1247:             * @return		0 if no error
1248:             */
1249:            private int do_before_completion() {
1250:                if (TraceTm.jotm.isDebugEnabled()) {
1251:                    TraceTm.jotm.debug("ControlImpl.do_before_completion()");
1252:                    TraceTm.jotm.debug("synchronizationList.size()="
1253:                            + synchronizationList.size());
1254:                }
1255:
1256:                int errors = 0;
1257:
1258:                for (int i = 0; i < synchronizationList.size(); i++) {
1259:
1260:                    RemoteSynchro sync = (RemoteSynchro) synchronizationList
1261:                            .get(i);
1262:
1263:                    try {
1264:                        sync.before_completion(this );
1265:                    } catch (Exception e) {
1266:                        TraceTm.jotm.error(
1267:                                "before_completion raised exception ", e);
1268:                        errors++;
1269:                    }
1270:                }
1271:                return errors;
1272:            }
1273:
1274:            /**
1275:             * Sends after_completion to the registered synchronizations
1276:             */
1277:            private void do_after_completion() {
1278:
1279:                if (TraceTm.jotm.isDebugEnabled()) {
1280:                    TraceTm.jotm.debug("ControlImpl.do_after_completion()");
1281:                    TraceTm.jotm.debug("status=" + mystatus);
1282:                    TraceTm.jotm.debug("synchronizationList.size()="
1283:                            + synchronizationList.size());
1284:                }
1285:
1286:                for (int i = 0; i < synchronizationList.size(); i++) {
1287:                    RemoteSynchro sync = (RemoteSynchro) synchronizationList
1288:                            .get(i);
1289:
1290:                    try {
1291:                        sync.after_completion(this , mystatus);
1292:                    } catch (Exception e) {
1293:                        TraceTm.jotm.error(
1294:                                "after_completion raised exception ", e);
1295:                    }
1296:                }
1297:            }
1298:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.