KickJava   Java API By Example, From Geeks To Geeks.

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


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: BMTStatelessTransactionInterceptor.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_COMMITTED JavaDoc;
29
30 import javax.ejb.EJBException JavaDoc;
31 import javax.transaction.InvalidTransactionException JavaDoc;
32 import javax.transaction.SystemException JavaDoc;
33 import javax.transaction.Transaction JavaDoc;
34
35 import org.objectweb.easybeans.api.EasyBeansInvocationContext;
36 import org.objectweb.easybeans.log.JLog;
37 import org.objectweb.easybeans.log.JLogFactory;
38
39 /**
40  * Defines an interceptor for method that are in Bean managed mode and then in Bean Managed Transaction.
41  * It is used by stateless session bean.
42  * @author Florent Benoit
43  */

44 public class BMTStatelessTransactionInterceptor extends AbsTransactionInterceptor {
45
46     /**
47      * Logger.
48      */

49     private JLog logger = JLogFactory.getLog(BMTStatelessTransactionInterceptor.class);
50
51     /**
52      * Constructor.<br>
53      * Acquire the transaction manager.
54      */

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

68     @Override JavaDoc
69     public Object JavaDoc intercept(final EasyBeansInvocationContext invocationContext) throws Exception JavaDoc {
70         logger.debug("Calling BMT TX interceptor");
71
72         // Get current transaction
73
Transaction JavaDoc transaction;
74         try {
75             transaction = getTransactionManager().getTransaction();
76         } catch (SystemException JavaDoc se) {
77             throw new EJBException JavaDoc("Cannot get the current transaction on transaction manager.", se);
78         }
79
80         logger.debug("Transaction found = {0}", transaction);
81
82         /*
83          * When a client invokes a business method via one of the enterprise
84          * bean's client view interfaces, the container suspends any transaction
85          * that may be associated with the client request. If there is a
86          * transaction associated with the instance (this would happen if a
87          * stateful session bean instance started the transaction in some
88          * previous business method), the container associates the method
89          * execution with this transaction. If there are interceptor methods
90          * associated with the bean instances, these actions are taken before
91          * the interceptor methods are invoked.
92          */

93
94         Transaction JavaDoc suspendedTransaction = null;
95         if (transaction != null) {
96             try {
97                 logger.debug("Suspending transaction {0}", transaction);
98                 suspendedTransaction = getTransactionManager().suspend();
99             } catch (SystemException JavaDoc se) {
100                 throw new EJBException JavaDoc("Cannot call suspend() on the transaction manager.", se);
101             }
102         }
103
104         boolean gotBusinessException = false;
105         try {
106             return invocationContext.proceed();
107         } catch (Exception JavaDoc e) {
108             gotBusinessException = true;
109             handleBeanManagedException(invocationContext, e);
110             // Shouldn't come here
111
return null;
112         } finally {
113             if (!gotBusinessException) {
114                 /**
115                  * If a stateless session bean instance starts a transaction in a
116                  * business method or interceptor method, it must commit the
117                  * transaction before the business method (or all its interceptor
118                  * methods) returns. The container must detect the case in which a
119                  * transaction was started, but not completed, in the business
120                  * method or interceptor method for the business method, and handle
121                  * it as follows:
122                  * <ul>
123                  * <li>Log this as an application error to alert the System
124                  * Administrator.</li>
125                  * <li>Roll back the started transaction</li>
126                  * <li>Discard the instance of the session bean</li>
127                  * <li>Throw the javax.ejb.EJBException[53]. If the EJB 2.1 client
128                  * view is used, the container should throw java.rmi.RemoteException
129                  * if the client is a remote client, or throw the
130                  * javax.ejb.EJBException if the client is a local client.</li>
131                  */

132                 Transaction JavaDoc transactionAfter = null;
133                 try {
134                     transactionAfter = getTransactionManager().getTransaction();
135                 } catch (SystemException JavaDoc se) {
136                     throw new EJBException JavaDoc("Cannot get the current transaction on transaction manager.", se);
137                 }
138                 if (transactionAfter != null) {
139                     int transactionStatus = transactionAfter.getStatus();
140                     // There is a transaction and it was not committed
141
if (transactionStatus != STATUS_COMMITTED) {
142                         String JavaDoc errMsg = "Transaction started by the bean but not committed.";
143                         // Log error
144
logger.error(errMsg);
145                         // Rollback
146
transactionAfter.rollback();
147                         //TODO: discard
148
// Throw Exception
149
throw new EJBException JavaDoc(errMsg);
150                     }
151                 }
152             }
153
154             /*
155              * The container resumes the suspended association when the business
156              * method has completed.
157              */

158             if (suspendedTransaction != null) {
159
160                 logger.debug("Resuming transaction {0}", transaction);
161
162                 try {
163                     getTransactionManager().resume(suspendedTransaction);
164                 } catch (InvalidTransactionException JavaDoc ite) {
165                     throw new EJBException JavaDoc(
166                             "Cannot call resume() on the given transaction. There is an invalid transaction", ite);
167                 } catch (IllegalStateException JavaDoc ise) {
168                     throw new EJBException JavaDoc(
169                             "Cannot call resume() on the given transaction. There is another associated transaction",
170                             ise);
171                 } catch (SystemException JavaDoc se) {
172                     throw new EJBException JavaDoc("Cannot call resume() on the given transaction. Unexpected error condition",
173                             se);
174                 }
175             }
176         }
177     }
178
179 }
180
Popular Tags