KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jts > CosTransactions > CurrentImpl


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * Copyright 2004-2005 Sun Microsystems, Inc. All rights reserved.
26  * Use is subject to license terms.
27  */

28 //----------------------------------------------------------------------------
29
//
30
// Module: CurrentImpl.java
31
//
32
// Description: Transaction Current pseudo-object implementation.
33
//
34
// Product: com.sun.jts.CosTransactions
35
//
36
// Author: Simon Holdsworth
37
//
38
// Date: March, 1997
39
//
40
// Copyright (c): 1995-1997 IBM Corp.
41
//
42
// The source code for this program is not published or otherwise divested
43
// of its trade secrets, irrespective of what has been deposited with the
44
// U.S. Copyright Office.
45
//
46
// This software contains confidential and proprietary information of
47
// IBM Corp.
48
//----------------------------------------------------------------------------
49

50 package com.sun.jts.CosTransactions;
51
52 // Import required classes.
53

54 import org.omg.CORBA.*;
55 import org.omg.PortableServer.*;
56 import org.omg.CosTransactions.*;
57
58 import com.sun.jts.otsidl.*;
59 import com.sun.jts.trace.*;
60 import java.util.logging.Logger JavaDoc;
61 import java.util.logging.Level JavaDoc;
62 import com.sun.logging.LogDomains;
63 import com.sun.jts.utils.LogFormatter;
64
65 /**The CurrentImpl class is our implementation of the standard Current
66  * interface. It provides operations that enable the demarcation of a
67  * transaction's scope. These operations are specified in pseudo-IDL. The
68  * CurrentImpl ensures that the CurrentTransaction class is set up when the
69  * CurrentImpl is created. As an instance of this class may be accessed from
70  * multiple threads within a process, serialisation for thread-safety is
71  * necessary in the implementation.
72  *
73  * @version 0.01
74  *
75  * @author Simon Holdsworth, IBM Corporation
76  *
77  * @see
78 */

79 //----------------------------------------------------------------------------
80
// CHANGE HISTORY
81
//
82
// Version By Change Description
83
// 0.01 SAJH Initial implementation.
84
//-----------------------------------------------------------------------------
85

86 public class CurrentImpl extends org.omg.CORBA.LocalObject JavaDoc
87     implements org.omg.CosTransactions.Current {
88     private int timeOut = 0;
89     private static boolean active = true;
90     private TransactionFactory factory = null;
91     /*
92         Logger to log transaction messages
93     */

94     static Logger JavaDoc _logger = LogDomains.getLogger(LogDomains.TRANSACTION_LOGGER);
95
96     /**Default CurrentImpl constructor.
97      *
98      * @param
99      *
100      * @return
101      *
102      * @see
103      */

104     CurrentImpl() {
105
106         // Ensure the CurrentTransaction state has been initialised.
107

108         CurrentTransaction.initialise();
109     }
110
111     /**Cleans up the state of the object.
112      *
113      * @param
114      *
115      * @return
116      *
117      * @see
118      */

119     public void finalize() {
120     }
121
122     /**Creates a new Control object, containing new Terminator and Coordinator
123      * objects.
124      * <p>
125      * The current timeout value is passed to the Coordinator.
126      * <p>
127      * The Control object is made the current one for the thread on which this
128      * method was invoked. If there is already a current Control the existing
129      * Control that represents the parent transaction is stacked behind the new one,
130      * which becomes the current one.
131      *
132      * @param
133      *
134      * @return
135      *
136      * @exception SubtransactionsUnavailable A subtransaction cannot be begun,
137      * either because the Transaction Service does not support nested transactions
138      * or because the current transaction is completing.
139      * @exception INVALID_TRANSACTION The transaction could not be begun as the
140      * current thread of control has pending non-transactional work.
141      * @exception SystemException The operation failed.
142      *
143      * @see
144      */

145     public void begin()
146         throws INVALID_TRANSACTION, SystemException, SubtransactionsUnavailable {
147
148         ControlImpl controlImpl = null;
149
150         // Until we need to check for resync in progress, synchronize the method.
151

152         synchronized(this) {
153
154             // If the transaction service is not active, throw an exception.
155

156             if( !active ) {
157                 NO_PERMISSION exc = new NO_PERMISSION(0,CompletionStatus.COMPLETED_NO);
158                 throw exc;
159             }
160
161             // Get a reference to the current ControlImpl object.
162

163             try {
164                 controlImpl = CurrentTransaction.getCurrent();
165             } catch( SystemException exc ) {
166             }
167
168             // Release the lock now so that if the TransactionFactoryImpl call has to block
169
// (during resync), the lock does not prevent other threads from running.
170

171         }
172
173         // If there is a current Control object, then we should try to begin a
174
// subtransaction.
175

176         if( controlImpl != null )
177             try {
178
179                 // Get the Coordinator reference, and use it to create a subtransaction.
180
// If an exception was raised, return it to the caller.
181

182                 Coordinator coord = controlImpl.get_coordinator();
183
184                 // Create a new Control object to represent the subtransaction.
185

186                 Control control = coord.create_subtransaction();
187
188                 // This control object may be remote, if the original Control object was.
189
// In this case we need to deal with it in the same was as we do in the
190
// resume method. Any exception which is thrown during this process will
191
// result in SubtransactionsUnavailable thrown to the caller.
192

193                 JControl jcontrol = JControlHelper.narrow(control);
194                 if( jcontrol != null )
195                     controlImpl = ControlImpl.servant(jcontrol);
196
197                 // If there is no local ControlImpl object for the transaction, we create one
198
// now.
199

200                 if( controlImpl == null )
201                     controlImpl = new ControlImpl(control);
202             } catch( Throwable JavaDoc exc ) {
203                 SubtransactionsUnavailable ex2 = new SubtransactionsUnavailable();
204                 throw ex2;
205             }
206
207         // If there is no current ControlImpl object, create a new top-level transaction
208

209         else {
210             //$ CurrentTransaction.report();
211
//$ RecoveryManager.report();
212
//$ ControlImpl.report();
213
//$ CoordinatorLog.report();
214
//$ TimeoutManager.report();
215
//
216
try {
217
218                 // Get the TransactionFactory which should be used from this application.
219
// This block must be synchronized so that different threads do not try
220
// this concurrently.
221

222                 synchronized(this) {
223                     if( factory == null )
224                         factory = Configuration.getFactory();
225                 }
226
227                 // Create the new transaction.
228

229                 if (factory != null) {
230                     if(_logger.isLoggable(Level.FINEST))
231                     {
232                         _logger.logp(Level.FINEST,"CurrentImpl","begin()",
233                                 "Before invoking create() on TxFactory");
234                     }
235  
236                     if (Configuration.isLocalFactory()) {
237                       controlImpl = ((TransactionFactoryImpl) factory).localCreate(timeOut);
238                     } else {
239                       Control control = factory.create(timeOut);
240
241                       // This control object is remote.
242
// In this case we need to deal with it in the same was as we do in the
243
// resume method. Any exception which is thrown during this process will
244
// result in SubtransactionsUnavailable thrown to the caller.
245

246                       JControl jcontrol = JControlHelper.narrow(control);
247                       if (jcontrol != null) {
248                           controlImpl = ControlImpl.servant(jcontrol);
249                       }
250
251                       // If there is no local ControlImpl object for the transaction, we create one
252
// now.
253

254                       if (controlImpl == null) {
255                           controlImpl = new ControlImpl(control);
256                       }
257                     }
258                 }
259             } catch( Throwable JavaDoc exc ) {
260                 _logger.log(Level.WARNING,
261                         "jts.unexpected_error_in_begin",exc);
262                         
263             }
264         }
265
266         // If the new Control reference is NULL, raise an error at this point.
267

268         if( controlImpl == null ){
269             INVALID_TRANSACTION exc = new INVALID_TRANSACTION(MinorCode.FactoryFailed,
270                                                               CompletionStatus.COMPLETED_NO);
271             throw exc;
272         }
273
274         // Make the new Control reference the current one, indicating that the
275
// existing one (if any) should be stacked.
276

277         else
278             try {
279                 if(_logger.isLoggable(Level.FINEST))
280                     {
281                         _logger.logp(Level.FINEST,"CurrentImpl","begin()",
282                                 "Before invoking CurrentTransaction.setCurrent(control,true)");
283                     }
284                 CurrentTransaction.setCurrent(controlImpl,true);
285             }
286
287         // The INVALID_TRANSACTION exception at this point indicates that the transaction
288
// may not be started. Clean up the state of the objects in the transaction.
289

290         catch( INVALID_TRANSACTION exc ) {
291             controlImpl.destroy();
292             throw (INVALID_TRANSACTION)exc.fillInStackTrace();
293         }
294
295     }
296
297     //START RI PERFIMPROVEMENT
298
// This method is introduced to improve the performance. without this method external
299
// synchronization is required to associate the timeout with this transaction
300
// This method is not part of the standard Current interface
301
/**Creates a new Control object, containing new Terminator and Coordinator
302      * objects.
303      * <p>
304      * Input parameter timeout value is passed to the Coordinator.
305      * <p>
306      * The Control object is made the current one for the thread on which this
307      * method was invoked. If there is already a current Control the existing
308      * Control that represents the parent transaction is stacked behind the new one,
309      * which becomes the current one.
310      *
311      * @param
312      *
313      * @return
314      *
315      * @exception SubtransactionsUnavailable A subtransaction cannot be begun,
316      * either because the Transaction Service does not support nested transactions
317      * or because the current transaction is completing.
318      * @exception INVALID_TRANSACTION The transaction could not be begun as the
319      * current thread of control has pending non-transactional work.
320      * @exception SystemException The operation failed.
321      *
322      * @see
323      */

324     public void begin(int time_out)
325         throws INVALID_TRANSACTION, SystemException, SubtransactionsUnavailable {
326
327         ControlImpl controlImpl = null;
328
329         // Until we need to check for resync in progress, synchronize the method.
330

331         synchronized(this) {
332
333             // If the transaction service is not active, throw an exception.
334

335             if( !active ) {
336                 NO_PERMISSION exc = new NO_PERMISSION(0,CompletionStatus.COMPLETED_NO);
337                 throw exc;
338             }
339
340             // Get a reference to the current ControlImpl object.
341

342             try {
343                 controlImpl = CurrentTransaction.getCurrent();
344             } catch( SystemException exc ) {
345             }
346
347             // Release the lock now so that if the TransactionFactoryImpl call has to block
348
// (during resync), the lock does not prevent other threads from running.
349

350         }
351
352         // If there is a current Control object, then we should try to begin a
353
// subtransaction.
354

355         if( controlImpl != null )
356             try {
357
358                 // Get the Coordinator reference, and use it to create a subtransaction.
359
// If an exception was raised, return it to the caller.
360

361                 Coordinator coord = controlImpl.get_coordinator();
362
363                 // Create a new Control object to represent the subtransaction.
364

365                 Control control = coord.create_subtransaction();
366
367                 // This control object may be remote, if the original Control object was.
368
// In this case we need to deal with it in the same was as we do in the
369
// resume method. Any exception which is thrown during this process will
370
// result in SubtransactionsUnavailable thrown to the caller.
371

372                 JControl jcontrol = JControlHelper.narrow(control);
373                 if( jcontrol != null )
374                     controlImpl = ControlImpl.servant(jcontrol);
375
376                 // If there is no local ControlImpl object for the transaction, we create one
377
// now.
378

379                 if( controlImpl == null )
380                     controlImpl = new ControlImpl(control);
381             } catch( Throwable JavaDoc exc ) {
382                 SubtransactionsUnavailable ex2 = new SubtransactionsUnavailable();
383                 throw ex2;
384             }
385
386         // If there is no current ControlImpl object, create a new top-level transaction
387

388         else {
389             //$ CurrentTransaction.report();
390
//$ RecoveryManager.report();
391
//$ ControlImpl.report();
392
//$ CoordinatorLog.report();
393
//$ TimeoutManager.report();
394
//
395
try {
396
397                 // Get the TransactionFactory which should be used from this application.
398
// This block must be synchronized so that different threads do not try
399
// this concurrently.
400

401                 synchronized(this) {
402                     if( factory == null )
403                         factory = Configuration.getFactory();
404                 }
405
406                 // Create the new transaction.
407

408                 if (factory != null) {
409                     if(_logger.isLoggable(Level.FINEST))
410                     {
411                         _logger.logp(Level.FINEST,"CurrentImpl","begin()",
412                                 "Before invoking create() on TxFactory");
413                     }
414  
415                     if (Configuration.isLocalFactory()) {
416                       controlImpl = ((TransactionFactoryImpl) factory).localCreate(time_out);
417                     } else {
418                       Control control = factory.create(time_out);
419
420                       // This control object is remote.
421
// In this case we need to deal with it in the same was as we do in the
422
// resume method. Any exception which is thrown during this process will
423
// result in SubtransactionsUnavailable thrown to the caller.
424

425                       JControl jcontrol = JControlHelper.narrow(control);
426                       if (jcontrol != null) {
427                           controlImpl = ControlImpl.servant(jcontrol);
428                       }
429
430                       // If there is no local ControlImpl object for the transaction, we create one
431
// now.
432

433                       if (controlImpl == null) {
434                           controlImpl = new ControlImpl(control);
435                       }
436                     }
437                 }
438             } catch( Throwable JavaDoc exc ) {
439                 _logger.log(Level.WARNING,
440                         "jts.unexpected_error_in_begin",exc);
441                         
442             }
443         }
444
445         // If the new Control reference is NULL, raise an error at this point.
446

447         if( controlImpl == null ){
448             INVALID_TRANSACTION exc = new INVALID_TRANSACTION(MinorCode.FactoryFailed,
449                                                               CompletionStatus.COMPLETED_NO);
450             throw exc;
451         }
452
453         // Make the new Control reference the current one, indicating that the
454
// existing one (if any) should be stacked.
455

456         else
457             try {
458                 if(_logger.isLoggable(Level.FINEST))
459                     {
460                         _logger.logp(Level.FINEST,"CurrentImpl","begin()",
461                                 "Before invoking CurrentTransaction.setCurrent(control,true)");
462                     }
463                 CurrentTransaction.setCurrent(controlImpl,true);
464             }
465
466         // The INVALID_TRANSACTION exception at this point indicates that the transaction
467
// may not be started. Clean up the state of the objects in the transaction.
468

469         catch( INVALID_TRANSACTION exc ) {
470             controlImpl.destroy();
471             throw (INVALID_TRANSACTION)exc.fillInStackTrace();
472         }
473
474     }
475     //END RI PERFIMPROVEMENT
476

477
478     /**Completes the current transaction.
479      * <p>
480      * This operation can only be called if there is a Terminator object available.
481      *
482      * @param reportHeuristics Indicates that heuristic exceptions should be
483      * passed back to the caller.
484      *
485      * @return
486      *
487      * @exception NoTransaction There is no current transaction to commit.
488      * @exception INVALID_TRANSACTION The current transaction has outstanding
489      * work and the Transaction Service is "checked".
490      * @exception NO_PERMISSION The caller is not allowed to commit the
491      * transaction.
492      * @exception TRANSACTION_ROLLEDBACK The transaction could not be committed,
493      * and has been rolled back.
494      * @exception HeuristicHazard Heuristic action may have been taken by a
495      * participant in the transaction.
496      * @exception HeuristicMixed Heuristic action has been taken by a participant
497      * in the transaction.
498      * @exception SystemException The operation failed.
499      *
500      * @see
501      */

502     public void commit( boolean reportHeuristics )
503         throws NO_PERMISSION, INVALID_TRANSACTION, TRANSACTION_ROLLEDBACK,
504         NoTransaction, HeuristicHazard, HeuristicMixed, SystemException {
505
506         // Get the current Control object. If there is none, raise the
507
// NoTransaction exception and return.
508

509         ControlImpl controlImpl = CurrentTransaction.getCurrent();
510         if( controlImpl == null ) {
511             NoTransaction exc = new NoTransaction();
512             throw exc;
513         }
514
515         // Get the local identifier from the Control object. Raise an exception if
516
// the transaction the Control represents has been completed.
517

518         int active = 1;
519
520         if( !controlImpl.representsRemoteControl() ) {
521
522             StatusHolder status = new StatusHolder();
523             Long JavaDoc localTID = new Long JavaDoc(controlImpl.getLocalTID(status));
524
525             if( status.value != Status.StatusActive ) {
526
527                 // added (Ram J) to handle asynchronous aborts. If a
528
// thread calls commit after an asynchronous abort happens,
529
// end the thread-tx association before throwing
530
// TRANSACTION_ROLLEDBACK exception.
531
// In the case where someone had called terminator.commit
532
// directly successfully, then end the thread association,
533
// before throwing INVALID_TRANSACTION exception.
534
CurrentTransaction.endCurrent(true);
535
536                 if( status.value == Status.StatusRolledBack ) {
537                     TRANSACTION_ROLLEDBACK exc =
538                         new TRANSACTION_ROLLEDBACK(0, CompletionStatus.COMPLETED_NO);
539                     throw exc;
540                 }
541
542                 INVALID_TRANSACTION exc = new INVALID_TRANSACTION(MinorCode.Completed,
543                                                                   CompletionStatus.COMPLETED_NO);
544                 throw exc;
545             }
546
547             // Check whether there are outstanding requests for this transaction, or
548
// other active threads.
549

550             active = controlImpl.numAssociated();
551         }
552
553         // If this is not the only active thread or there are outstanding requests,
554
// raise an exception and return.
555

556         if( (active != 1) || (controlImpl.isOutgoing()) ) {
557             if( active != 1 ) {
558             }
559
560             if( controlImpl.isOutgoing() ) {
561             }
562
563             INVALID_TRANSACTION exc = new INVALID_TRANSACTION(MinorCode.DeferredActivities,
564                                                               CompletionStatus.COMPLETED_NO);
565             throw exc;
566         }
567
568         // Get the Terminator from the current Control object. If this fails, then
569
// return whatever exception was raised to the caller.
570

571         else {
572             Terminator JavaDoc term = null;
573
574             if (Configuration.isLocalFactory()) {
575               try {
576                 term = controlImpl.get_localTerminator();
577               } catch (Throwable JavaDoc exc) {
578                 NO_PERMISSION ex2 = new NO_PERMISSION(0,CompletionStatus.COMPLETED_NO);
579                 throw ex2;
580               }
581             } else {
582               try {
583                   term = controlImpl.get_terminator();
584               } catch( Throwable JavaDoc exc ) {
585                 NO_PERMISSION ex2 = new NO_PERMISSION(0,CompletionStatus.COMPLETED_NO);
586                 throw ex2;
587               }
588
589               // Tell the Terminator to commit the transaction.
590
// This will end the current association of the transaction, if the
591
// Terminator is local. If the Terminator is remote, we end the association
592
// ourselves, and do not request unstacking as there will be no stacked
593
// Control.
594

595               // End the association if the Terminator is remote. This is done under a
596
// local environment to ignore any exception. This must be done before
597
// the Terminator is called otherwise the ControlImpl object will get
598
// confused.
599

600               try {
601                 if( Configuration.getProxyChecker().isProxy(term) )
602                     CurrentTransaction.endCurrent(true);
603               } catch( Throwable JavaDoc exc ) {}
604             }
605             // Commit the transaction.
606

607         try{
608                 term.commit(reportHeuristics);
609             } catch (TRANSACTION_ROLLEDBACK e) {
610                 // ADDED (Ram J) (10/15/01) To handle asynchronous aborts. End
611
// thread-tx association before re-throwing exception. This is
612
// because commit/rollback operation by a different thread
613
// does not set all other thread's control's status to INACTIVE
614
// anymore, for performance purposes.
615
CurrentTransaction.endCurrent(true);
616                 throw e;
617             }
618
619             // Free the ControlImpl object.
620

621             controlImpl.destroy();
622         }
623
624     }
625
626     /**Rolls back the changes performed under the current transaction.
627      * <p>
628      * This operation can only be called if there is a Terminator object available.
629      *
630      * @param
631      *
632      * @return
633      *
634      * @exception NoTransaction There is no current transaction to rollback.
635      * @exception INVALID_TRANSACTION The current transaction has outstanding
636      * work and the Transaction Service is "checked".
637      * @exception NO_PERMISSION The caller is not allowed to roll the
638      * transaction back.
639      * @exception TRANSACTION_ROLLEDBACK The transaction has already been rolled
640      * back.
641      * @exception SystemException The operation failed.
642      *
643      * @see
644      */

645     public void rollback()
646         throws NoTransaction, INVALID_TRANSACTION, NO_PERMISSION,
647         TRANSACTION_ROLLEDBACK, SystemException {
648
649         ControlImpl controlImpl = CurrentTransaction.getCurrent();
650
651         if( controlImpl == null ) {
652             NoTransaction exc = new NoTransaction();
653             throw exc;
654         }
655
656         // Get the local identifier from the Control object. Raise an exception if
657
// the transaction the Control represents has been completed.
658

659         int active = 1;
660
661         if( !controlImpl.representsRemoteControl() ) {
662
663             StatusHolder status = new StatusHolder();
664             Long JavaDoc localTID = new Long JavaDoc(controlImpl.getLocalTID(status));
665
666             if( status.value != Status.StatusActive ) {
667
668                 // added (Ram J) to handle asynchronous aborts. If a
669
// thread calls rollback after an asynchronous abort happens,
670
// end the thread-tx association before throwing
671
// TRANSACTION_ROLLEDBACK exception.
672
// In the case where someone had called terminator.commit
673
// directly successfully, then end the thread association,
674
// before throwing INVALID_TRANSACTION exception.
675
CurrentTransaction.endCurrent(true);
676
677                 if( status.value == Status.StatusRolledBack ) {
678                     /* TN - do not throw rollback exception
679                     TRANSACTION_ROLLEDBACK exc = new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_NO);
680                     throw exc;
681                     */

682                     return;
683                 }
684
685                 INVALID_TRANSACTION exc = new INVALID_TRANSACTION(MinorCode.Completed,
686                                                                   CompletionStatus.COMPLETED_NO);
687                 throw exc;
688             }
689
690             // Check whether there are outstanding requests for this transaction, or
691
// other active threads.
692

693             active = controlImpl.numAssociated();
694         }
695
696         // If this is not the only active thread or there are outstanding requests,
697
// raise an exception and return.
698

699         if( (active != 1) || (controlImpl.isOutgoing()) ) {
700             if( active != 1 ) {
701             }
702
703             if( controlImpl.isOutgoing() ) {
704             }
705
706             INVALID_TRANSACTION exc = new INVALID_TRANSACTION(MinorCode.DeferredActivities,
707                                                               CompletionStatus.COMPLETED_NO);
708             throw exc;
709         }
710
711         // Get the Terminator from the current Control object. If this fails, then
712
// return whatever exception was raised to the caller.
713

714         else {
715             Terminator JavaDoc term = null;
716
717             if (Configuration.isLocalFactory()) {
718               try {
719                   term = controlImpl.get_localTerminator();
720               } catch( Unavailable exc ) {
721                 NO_PERMISSION ex2 = new NO_PERMISSION(0,CompletionStatus.COMPLETED_NO);
722                 throw ex2;
723               }
724             } else {
725               try {
726                 term = controlImpl.get_terminator();
727               } catch( Unavailable exc ) {
728                 NO_PERMISSION ex2 = new NO_PERMISSION(0,CompletionStatus.COMPLETED_NO);
729                 throw ex2;
730               }
731
732               // Tell the Terminator to roll the transaction back.
733
// This will end the current association of the transaction, if the
734
// Terminator is local. If the Terminator is remote, we end the association
735
// ourselves, and do not request unstacking as there will be no stacked
736
// Control.
737

738               // End the association if the Terminator is remote. This is done under a
739
// local environment to ignore any exception. This must be done before
740
// the Terminator is called otherwise the ControlImpl object will get
741
// confused.
742

743               try {
744                 if( Configuration.getProxyChecker().isProxy(term) )
745                     CurrentTransaction.endCurrent(true);
746               } catch( Throwable JavaDoc exc ) {}
747             }
748             // Roll the transaction back.
749

750             try{
751                 term.rollback();
752             } catch (TRANSACTION_ROLLEDBACK e) {
753                 // ADDED (Ram J) (10/15/01) To handle asynchronous aborts. End
754
// thread-tx association before re-throwing exception. This is
755
// because commit/rollback operation by a different thread
756
// does not set all other thread's control's status to INACTIVE
757
// anymore, for performance purposes.
758
CurrentTransaction.endCurrent(true);
759                 //throw e; // no need to throw this for rollback operation.
760
}
761
762             // Free the ControlImpl object.
763

764             controlImpl.destroy();
765         }
766
767     }
768
769     /**Marks the current transaction such that is cannot be committed and only
770      * rolled back.
771      *
772      * @param
773      *
774      * @return
775      *
776      * @exception NoTransaction There is no current transaction to mark rollback-
777      * only.
778      *
779      * @see
780      */

781     public void rollback_only()
782         throws NoTransaction {
783
784         // Get the reference of the current Coordinator. If there is none, raise the
785
// NoTransaction exception.
786

787         try {
788             Coordinator coord = CurrentTransaction.getCurrentCoordinator();
789
790             // Tell the Coordinator to mark itself rollback-only.
791

792             coord.rollback_only();
793         } catch( Throwable JavaDoc exc ) {
794             throw new NoTransaction();
795         }
796
797     }
798
799     /**Returns the status of the current transaction.
800      *
801      * @param
802      *
803      * @return The current status of the transaction. If there is no
804      * current transaction, the value StatusNoTransaction is returned.
805      *
806      * @see
807      */

808     public Status get_status() {
809
810         Status result = Status.StatusNoTransaction;
811         try {
812             Coordinator coord = CurrentTransaction.getCurrentCoordinator();
813
814             // Ask the Coordinator object for its status, and return the value.
815

816             if( coord != null )
817                 result = coord.get_status();
818         } catch( Unavailable exc ) {
819         } catch( TRANSACTION_ROLLEDBACK exc ) {
820             result = Status.StatusRolledBack;
821         } catch( SystemException exc ) {
822             result = Status.StatusUnknown;
823         }
824
825         return result;
826     }
827
828     /**Returns a printable string representing the current transaction.
829      *
830      * @param
831      *
832      * @return The transaction name. If there is no current transaction,
833      * null is returned.
834      *
835      * @see
836      */

837     public String JavaDoc get_transaction_name() {
838
839         String JavaDoc result = null;
840         try {
841             Coordinator coord = CurrentTransaction.getCurrentCoordinator();
842
843             // Ask the Coordinator object for its name, and return the value.
844

845             if( coord != null )
846                 result = coord.get_transaction_name();
847         }
848
849         // Ignore Unavailable (return null in this case), but allow other exceptions
850
// to percolate up.
851

852         catch( Unavailable exc ) {}
853
854         return result;
855     }
856
857     /**Sets the timeout value to be used for all subsequent transactions.
858      *
859      * @param timeout The timeout value in seconds.
860      *
861      * @return
862      *
863      * @see
864      */

865     public void set_timeout( int timeout ) {
866         // timeout < 0 will be rejected (no op).
867
// timeout = 0 implies tx has no timeout or a default timeout is used.
868
// timeout > 0 implies tx will timeout at the end of the duration.
869
if (timeout >= 0) {
870             timeOut = timeout;
871         }
872     }
873
874     public int get_timeout() {
875     return timeOut;
876     }
877
878     /**Returns the current ControlImpl object.
879      *
880      * @param
881      *
882      * @return The Control object for the current transaction, or null
883      * if there is no current transaction.
884      *
885      * @exception TRANSACTION_ROLLEDBACK The current transaction has been rolled
886      * back.
887      *
888      * @see
889      */

890     public Control get_control()
891         throws TRANSACTION_ROLLEDBACK {
892         Control result = null;
893
894         // Get the current Control reference from the TransactionManager. If there
895
// is none, return a NULL pointer.
896
// If the current Control object indicates that the transaction has ended,
897
// then the current association will be ended and the TRANSACTION_ROLLEDBACK
898
// exception will be raised.
899

900         ControlImpl control = CurrentTransaction.getCurrent();
901         if (control != null) {
902           if (Configuration.isLocalFactory()) {
903             result = (Control) control;
904           } else {
905             result = control.object();
906           }
907         }
908
909         return result;
910     }
911
912     /**Disassociates the current ControlImpl from the calling thread.
913      *
914      * @param
915      *
916      * @return The Control object for the suspended transaction. If
917      * there was no transaction, this will be null.
918      *
919      * @see
920      */

921     public Control suspend() {
922         Control result = null;
923         ControlImpl cImpl = CurrentTransaction.endCurrent(false);
924         if(_logger.isLoggable(Level.FINEST))
925         {
926             _logger.logp(Level.FINEST,"CurrentImpl","suspend()",
927                     "Current thread has been disassociated from control :"
928                     +cImpl);
929         }
930
931         if (Configuration.isLocalFactory()) {
932             result = (Control) cImpl;
933         } else {
934           if (cImpl != null) {
935             result = cImpl.object();
936           }
937         }
938
939         return result;
940     }
941
942     /**Re-associates the given Control to the calling thread.
943      * <p>
944      * If there is already a current ControlImpl, it is replaced as the current one.
945      *
946      * @param control The Control object to be made current.
947      *
948      * @return
949      *
950      * @exception InvalidControl The Control object passed as a parameter is
951      * not valid. This may be because the transaction it represents has
952      * already completed, or because the object is of the wrong type.
953      * @exception INVALID_TRANSACTION The transaction could not be begun as the
954      * current thread of control has pending non-transactional work.
955      *
956      * @see
957      */

958     public void resume( Control control )
959         throws InvalidControl, INVALID_TRANSACTION {
960
961         ControlImpl contImpl = null;
962
963         // If the Control object is NULL, then this operation is actually a suspend
964
// operation, so end the current association with the thread.
965

966         if( control == null )
967             CurrentTransaction.endCurrent(false);
968         else {
969
970             if (Configuration.isLocalFactory()) {
971                 contImpl = (ControlImpl) control;
972             } else {
973               // Check the ControlImpl object is valid.
974
JControl jcontrol = JControlHelper.narrow(control);
975
976               // Try to locate the local ControlImpl object for the transaction.
977

978               if( jcontrol != null )
979                 contImpl = ControlImpl.servant(jcontrol);
980
981               // If there is no local ControlImpl object for the transaction, we create one
982
// now.
983

984               if( contImpl == null )
985                 try {
986                     contImpl = new ControlImpl(control);
987                 } catch( Exception JavaDoc exc ) {
988
989                     InvalidControl ex2 = new InvalidControl();
990                     throw ex2;
991                 }
992              }
993
994             // End the current association regardless of whether there is one.
995
// Attempt to make the given ControlImpl object the current one.
996

997             try {
998                 CurrentTransaction.endCurrent(false);
999                 CurrentTransaction.setCurrent(contImpl,false);
1000                if(_logger.isLoggable(Level.FINEST))
1001                {
1002                    _logger.logp(Level.FINEST,"CurrentImpl","resume(control)",
1003                            "Current thread has been associated with control :"
1004                            +contImpl);
1005                }
1006            }
1007
1008            // The INVALID_TRANSACTION exception at this point indicates that the transaction
1009
// may not be resumed.
1010

1011            catch( INVALID_TRANSACTION exc ) {
1012                throw (INVALID_TRANSACTION)exc.fillInStackTrace();
1013            }
1014        }
1015
1016    }
1017
1018    /**Shuts down all services.
1019     *
1020     * @param immediate Indicates whether to ignore running transactions.
1021     *
1022     * @return
1023     *
1024     * @see
1025     */

1026
1027    synchronized void shutdown( boolean immediate ) {
1028
1029        // Inform the basic transaction services to shutdown.
1030

1031        CurrentTransaction.shutdown(immediate);
1032
1033    }
1034
1035    /**Prevents any further transactional activity in the process.
1036     *
1037     * @param
1038     *
1039     * @return
1040     *
1041     * @see
1042     */

1043    static void deactivate() {
1044        active = false;
1045    }
1046
1047    //
1048
// Provide a dummy routine to satisfy the abstract method inherited from org.omg.CosTransactions.Current
1049
//
1050
public String JavaDoc[] _ids() {
1051        return null;
1052    }
1053}
1054
Popular Tags