KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > transaction > JTATransactionController


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
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
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 in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2005, Oracle. All rights reserved.
22
package oracle.toplink.essentials.transaction;
23
24 import javax.transaction.*;
25 import oracle.toplink.essentials.exceptions.TransactionException;
26
27 /**
28  * <p>
29  * <b>Purpose</b>: TransactionController implementation for JTA 1.0
30  * <p>
31  * <b>Description</b>: Implements the required behaviour for controlling JTA 1.0
32  * transactions. Specific JTA implementations may need to extend this class
33  * when special controller behavior is necessary.
34  * <p>
35  * The JTA TransactionManager must be obtained and set on the
36  * instance in order for a Synchronization listener to be registered against
37  * the transaction. This can be done either by extending this class and defining
38  * acquireTransactionManager() to return the manager for the server, or by using
39  * this class and explicitly calling the setTransactionManager() method on it
40  * after the fact.
41  * e.g.
42  * TransactionManager mgr = controller.jndiLookup("java:comp/TransactionManager");
43  * controller.setTransactionManager(mgr);
44  * <p>
45  * If a different listener needs to be used for synchronization, the
46  * SynchronizationListenerFactory should be set on the controller instance.
47  * The listener subclass should implement the factory interface, so that
48  * setting the factory is simply a matter of assigning an instance of the
49  * listener.
50  * e.g.
51  * controller.setSynchronizationListenerFactory(
52  * new DifferentServerSynchronizationListener());
53  *
54  * The default listener factory creates instances of JTATransactionListener.
55  * <p>
56  * @see JTASynchronizationListener
57  * @see AbstractTransactionController
58  */

59 public class JTATransactionController extends AbstractTransactionController {
60     // Primary point of integration with JTA
61
protected TransactionManager transactionManager;
62
63     /**
64      * PUBLIC:
65      * Return a new controller for use with a JTA 1.0 compliant TransactionManager.
66      */

67     public JTATransactionController() {
68         super();
69         listenerFactory = (SynchronizationListenerFactory)new JTASynchronizationListener();
70         try {
71             transactionManager = acquireTransactionManager();
72         } catch (Exception JavaDoc ex) {
73             throw TransactionException.errorObtainingTransactionManager(ex);
74         }
75     }
76
77     /**
78      * INTERNAL:
79      * Register the specified synchronization listener with the given active
80      * transaction.
81      *
82      * @param listener The synchronization listener created for this transaction
83      * @param txn The active transaction for which notification is being requested
84      */

85     protected void registerSynchronization_impl(AbstractSynchronizationListener listener, Object JavaDoc txn) throws Exception JavaDoc {
86         ((Transaction)txn).registerSynchronization((Synchronization)listener);
87     }
88
89     /**
90      * INTERNAL:
91      * Return the active external transaction, or null if none is currently
92      * active for this thread.
93      *
94      * @return The active transaction object or id, or null if no transaction is active
95      */

96     protected Object JavaDoc getTransaction_impl() throws Exception JavaDoc {
97         return getTransactionManager().getTransaction();
98     }
99
100     /**
101      * INTERNAL:
102      * Return a key for the specified external transaction object.
103      * The key is just something that can be inserted into a hashtable (must support
104      * hashCode() and equals() methods).
105      *
106      * @param transaction The transaction to which the returned key applies (may be null)
107      * @return A key for the passed in transaction, or null if no transaction specified
108      */

109     protected Object JavaDoc getTransactionKey_impl(Object JavaDoc transaction) throws Exception JavaDoc {
110         // Use the transaction itself as the key
111
return transaction;
112     }
113
114     /**
115      * INTERNAL:
116      * Return the transaction status as an object. We will pass around Integers that
117      * wrap the int JTA status values.
118      *
119      * @return The current transaction status
120      */

121     protected Object JavaDoc getTransactionStatus_impl() throws Exception JavaDoc {
122         return new Integer JavaDoc(getTransactionManager().getStatus());
123     }
124
125     /**
126      * INTERNAL:
127      * Begin an external transaction.
128      */

129     protected void beginTransaction_impl() throws Exception JavaDoc {
130         getTransactionManager().begin();
131     }
132
133     /**
134      * INTERNAL:
135      * Commit the external transaction.
136      */

137     protected void commitTransaction_impl() throws Exception JavaDoc {
138         getTransactionManager().commit();
139     }
140
141     /**
142      * INTERNAL:
143      * Roll back the external transaction.
144      */

145     protected void rollbackTransaction_impl() throws Exception JavaDoc {
146         getTransactionManager().rollback();
147     }
148
149     /**
150      * INTERNAL:
151      * Mark the external transaction for rollback.
152      */

153     protected void markTransactionForRollback_impl() throws Exception JavaDoc {
154         getTransactionManager().setRollbackOnly();
155     }
156
157     /**
158      * INTERNAL:
159      * Return true if the status indicates that a transaction can be started. This
160      * would normally mean that no transaction is currently active.
161      *
162      * @param status The current transaction status
163      * @return true if the current state allows for a transaction to be started
164      */

165     protected boolean canBeginTransaction_impl(Object JavaDoc status) {
166         return getIntStatus(status) == Status.STATUS_NO_TRANSACTION;
167     }
168
169     /**
170      * INTERNAL:
171      * Return true if the status indicates that a transaction can be committed. This
172      * would normally mean that a transaction is currently active.
173      *
174      * @param status The current transaction status
175      * @return true if the current state allows for a transaction to be committed
176      */

177     protected boolean canCommitTransaction_impl(Object JavaDoc status) {
178         return getIntStatus(status) == Status.STATUS_ACTIVE;
179     }
180
181     /**
182      * INTERNAL:
183      * Return true if the status indicates that a transaction can be rolled back. This
184      * would normally mean that a transaction is currently active.
185      *
186      * @param status The current transaction status
187      * @return true if the current state allows for a transaction to be rolled back
188      */

189     protected boolean canRollbackTransaction_impl(Object JavaDoc status) {
190         return getIntStatus(status) == Status.STATUS_ACTIVE;
191     }
192
193     /**
194      * INTERNAL:
195      * Return true if the status indicates that the SQL should be issued to the db.
196      * This would normally mean that a transaction was active.
197      *
198      * @param status The current transaction status
199      * @return true if the current state allows for the SQL to be sent to the database
200      */

201     protected boolean canIssueSQLToDatabase_impl(Object JavaDoc status) {
202         int stat = getIntStatus(status);
203         return ((stat == Status.STATUS_ACTIVE) || (stat == Status.STATUS_PREPARING));
204     }
205
206     /**
207      * INTERNAL:
208      * Return true if the status indicates that the unit of work should be merged
209      * into the shared cache. This would normally mean that the transaction was
210      * committed successfully.
211      *
212      * @param status The current transaction status
213      * @return true if the current state dictates that the unit of work should be merged
214      */

215     protected boolean canMergeUnitOfWork_impl(Object JavaDoc status) {
216         return getIntStatus(status) == Status.STATUS_COMMITTED;
217     }
218
219     /**
220      * INTERNAL:
221      * Return true if the transaction is rolled back.
222      */

223     public boolean isRolledBack_impl(Object JavaDoc status) {
224         return getIntStatus(status) == Status.STATUS_ROLLEDBACK;
225     }
226
227     /**
228      * INTERNAL:
229      * Obtain and return the JTA TransactionManager on this platform.
230      * By default do nothing.
231      *
232      * This method can be can be overridden by subclasses to obtain the
233      * transaction manager by whatever means is appropriate to the server.
234      * This method is invoked by the constructor to initialize the transaction
235      * manager at instance-creation time. Alternatively the transaction manager
236      * can be set directly on the controller instance using the
237      * setTransactionManager() method after the instance has been created.
238      *
239      * @return The TransactionManager for the transaction system
240      */

241     protected TransactionManager acquireTransactionManager() throws Exception JavaDoc {
242         return null;
243     }
244
245     /**
246      * INTERNAL:
247      * Convenience method to return the int value of the transaction status.
248      * Assumes that the status object is an Integer.
249      */

250     protected int getIntStatus(Object JavaDoc status) {
251         return ((Integer JavaDoc)status).intValue();
252     }
253
254     /**
255      * PUBLIC:
256      * Return the transaction manager used to control the JTA transactions.
257      *
258      * @return The JTA TransactionManager that is used to obtain transaction
259      * state information and control the active transaction.
260      */

261     public TransactionManager getTransactionManager() {
262         return transactionManager;
263     }
264
265     /**
266      * PUBLIC:
267      * Set the transaction manager used to control the JTA transactions.
268      *
269      * @param mgr A valid JTA TransactionManager that can be
270      * accessed by this controller to obtain transaction state information and
271      * control the active transaction.
272      */

273     public void setTransactionManager(TransactionManager mgr) {
274         transactionManager = mgr;
275     }
276
277     /**
278      * INTERNAL:
279      * Convert the status to a string for tracing.
280      */

281     static String JavaDoc[] codes = { "STATUS_ACTIVE", "MARKED_ROLLBACK", "PREPARED", "COMMITTED", "ROLLEDBACK", "UNKNOWN", "NO_TRANSACTION", "PREPARING", "COMMITTING", "ROLLING_BACK" };
282
283     protected String JavaDoc statusToString_impl(Object JavaDoc status) {
284         int statusCode = getIntStatus(status);
285         return codes[statusCode];
286     }
287 }
288
Popular Tags