KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > easybeans > transaction > interceptors > CMTRequiresNewTransactionInterceptor


1 /**
2  * EasyBeans
3  * Copyright (C) 2006 Bull S.A.S.
4  * Contact: easybeans@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: CMTRequiresNewTransactionInterceptor.java 942 2006-07-26 09:17:13Z benoitf $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.easybeans.transaction.interceptors;
27
28 import static javax.transaction.Status.STATUS_ACTIVE JavaDoc;
29 import static javax.transaction.Status.STATUS_MARKED_ROLLBACK JavaDoc;
30
31 import javax.ejb.EJBException JavaDoc;
32 import javax.ejb.TransactionRolledbackLocalException JavaDoc;
33 import javax.transaction.InvalidTransactionException JavaDoc;
34 import javax.transaction.NotSupportedException JavaDoc;
35 import javax.transaction.RollbackException JavaDoc;
36 import javax.transaction.SystemException JavaDoc;
37 import javax.transaction.Transaction JavaDoc;
38
39 import org.objectweb.easybeans.api.EasyBeansInvocationContext;
40 import org.objectweb.easybeans.log.JLog;
41 import org.objectweb.easybeans.log.JLogFactory;
42
43 /**
44  * Defines an interceptor for method using the REQUIRES_NEW attribute.
45  * @author Florent Benoit
46  */

47 public class CMTRequiresNewTransactionInterceptor extends AbsTransactionInterceptor {
48
49     /**
50      * Logger.
51      */

52     private JLog logger = JLogFactory.getLog(CMTRequiresNewTransactionInterceptor.class);
53
54
55     /**
56      * Constructor.<br>
57      * Acquire the transaction manager.
58      */

59     public CMTRequiresNewTransactionInterceptor() {
60         super();
61     }
62
63     /**
64      * Execute transaction as specified with the REQUIRES_NEW attribute.
65      * @param invocationContext context with useful attributes on the current
66      * invocation
67      * @return result of the next invocation (to chain interceptors)
68      * @throws Exception if interceptor fails
69      * @see <a HREF="http://www.jcp.org/en/jsr/detail?id=220">EJB 3.0
70      * specification 12.6.2.4</a>
71      */

72     @Override JavaDoc
73     public Object JavaDoc intercept(final EasyBeansInvocationContext invocationContext) throws Exception JavaDoc {
74         logger.debug("Calling RequiresNew TX interceptor");
75
76         // Get current transaction
77
Transaction JavaDoc transaction;
78         try {
79             transaction = getTransactionManager().getTransaction();
80         } catch (SystemException JavaDoc se) {
81             throw new EJBException JavaDoc("Cannot get the current transaction on transaction manager.", se);
82         }
83
84         logger.debug("Transaction found = {0}", transaction);
85
86
87         /*
88          * If a client calls with a transaction context, the container
89          * suspends the association of the transaction context with the
90          * current thread before starting the new transaction and invoking
91          * the business method. The container resumes the suspended
92          * transaction association after the business method and the new
93          * transaction have been completed.
94          */

95         // Existing transaction
96
Transaction JavaDoc suspendedTransaction = null;
97         if (transaction != null) {
98             try {
99                 logger.debug("Suspending transaction {0}", transaction);
100                 suspendedTransaction = getTransactionManager().suspend();
101             } catch (SystemException JavaDoc se) {
102                 throw new EJBException JavaDoc("Cannot call suspend() on the transaction manager.", se);
103             }
104         }
105
106         /*
107          * If the client invokes the enterprise bean's method while the client
108          * is not associated with a transaction context, the container
109          * automatically starts a new transaction before delegating a method
110          * call to the enterprise bean business method. The container
111          * automatically enlists all the resource managers accessed by the
112          * business method with the transaction. If the business method invokes
113          * other enterprise beans, the container passes the transaction context
114          * with the invocation. The container attempts to commit the transaction
115          * when the business method has completed. The container performs the
116          * commit protocol before the method result is sent to the client.
117          */

118         try {
119             getTransactionManager().begin();
120         } catch (NotSupportedException JavaDoc nse) {
121             throw new EJBException JavaDoc("Transaction Manager implementation does not support nested transactions.", nse);
122         } catch (SystemException JavaDoc se) {
123             throw new EJBException JavaDoc("Cannot call begin() on the transaction manager.", se);
124         }
125
126         boolean gotBusinessException = false;
127         try {
128             return invocationContext.proceed();
129         } catch (Exception JavaDoc e) {
130             gotBusinessException = true;
131             handleContextContainerTransaction(invocationContext, e);
132
133             // Shouldn't come here
134
return null;
135         } finally {
136
137             // only do some operations if transaction has been started before
138
// invoking the method.
139
if (!gotBusinessException) {
140                 // sanity check.
141
Transaction JavaDoc transactionAfter = null;
142                 try {
143                     transactionAfter = getTransactionManager().getTransaction();
144                 } catch (SystemException JavaDoc se) {
145                     throw new EJBException JavaDoc("Cannot get the current transaction on transaction manager.", se);
146                 }
147
148                 if (transactionAfter == null) {
149                     throw new EJBException JavaDoc("Transaction disappeared.");
150                 }
151
152                 /*
153                  * The container attempts to commit the transaction when the
154                  * business method has completed. The container performs the
155                  * commit protocol before the method result is sent to the
156                  * client.
157                  */

158                 try {
159                     switch (getTransactionManager().getStatus()) {
160                     case STATUS_ACTIVE:
161                         getTransactionManager().commit();
162                         break;
163                     case STATUS_MARKED_ROLLBACK:
164                         getTransactionManager().rollback();
165                         break;
166                     default:
167                         throw new RuntimeException JavaDoc("Unexpected transaction status" + getTransactionManager().getStatus());
168                     }
169                 } catch (RollbackException JavaDoc e) {
170                     throw new TransactionRolledbackLocalException JavaDoc("Could not commit transaction", e);
171                 } catch (Exception JavaDoc e) {
172                     throw new EJBException JavaDoc("Container exception", e);
173                 }
174             }
175
176             // if it was suspended
177
if (suspendedTransaction != null) {
178
179                 logger.debug("Resuming transaction {0}", transaction);
180
181                 try {
182                     getTransactionManager().resume(suspendedTransaction);
183                 } catch (InvalidTransactionException JavaDoc ite) {
184                     throw new EJBException JavaDoc(
185                             "Cannot call resume() on the given transaction. There is an invalid transaction", ite);
186                 } catch (IllegalStateException JavaDoc ise) {
187                     throw new EJBException JavaDoc(
188                             "Cannot call resume() on the given transaction. There is another associated transaction",
189                             ise);
190                 } catch (SystemException JavaDoc se) {
191                     throw new EJBException JavaDoc("Cannot call resume() on the given transaction. Unexpected error condition",
192                             se);
193                 }
194             }
195         }
196     }
197
198 }
199
Popular Tags