KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > transaction > jta > OC4JJtaTransactionManager


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.transaction.jta;
18
19 import java.lang.reflect.InvocationTargetException JavaDoc;
20 import java.lang.reflect.Method JavaDoc;
21
22 import javax.transaction.NotSupportedException JavaDoc;
23 import javax.transaction.SystemException JavaDoc;
24 import javax.transaction.Transaction JavaDoc;
25 import javax.transaction.UserTransaction JavaDoc;
26
27 import org.springframework.transaction.TransactionDefinition;
28 import org.springframework.transaction.TransactionSystemException;
29 import org.springframework.util.ClassUtils;
30
31 /**
32  * Special {@link JtaTransactionManager} variant for Oracle OC4J (10.1.3 and higher).
33  * Supports the full power of Spring's transaction definitions on OC4J's
34  * transaction coordinator, <i>beyond standard JTA</i>: transaction names
35  * and per-transaction isolation levels.
36  *
37  * <p>Uses OC4J's special <code>begin(name)</code> method to start a JTA transaction,
38  * in orderto make <b>Spring-driven transactions visible in OC4J's transaction
39  * monitor</b>. In case of Spring's declarative transactions, the exposed name will
40  * (by default) be the fully-qualified class name + "." + method name.
41  *
42  * <p>Supports a <b>per-transaction isolation level</b> through OC4J's corresponding
43  * <code>OC4JTransaction.setTransactionIsolation(int)</code> method. This will
44  * apply the specified isolation level (e.g. ISOLATION_SERIALIZABLE) to all
45  * JDBC Connections that participate in the given transaction.
46  *
47  * <p>Automatically detects the available OC4J server version and adapts accordingly.
48  *
49  * <p>By default, the JTA UserTransaction and TransactionManager handles are
50  * fetched directly from OC4J's <code>TransactionUtility</code> in 10.1.3.2.
51  * This can be overridden by specifying "userTransaction"/"userTransactionName"
52  * and "transactionManager"/"transactionManagerName", passing in existing handles
53  * or specifying corresponding JNDI locations to look up.
54  *
55  * <p>Thanks to Oracle for donating the original version of this extended OC4J
56  * integration code to the Spring project!
57  *
58  * @author Paul Parkinson
59  * @author Juergen Hoeller
60  * @since 2.0.3
61  * @see org.springframework.transaction.TransactionDefinition#getName
62  * @see org.springframework.transaction.TransactionDefinition#getIsolationLevel
63  * @see com.evermind.server.ApplicationServerTransactionManager#begin(String)
64  * @see com.evermind.server.ApplicationServerTransaction#setTransactionIsolation
65  * @see oracle.j2ee.transaction.TransactionUtility
66  */

67 public class OC4JJtaTransactionManager extends JtaTransactionManager {
68
69     private static final String JavaDoc TRANSACTION_UTILITY_CLASS_NAME =
70             "oracle.j2ee.transaction.TransactionUtility";
71
72     private static final String JavaDoc TRANSACTION_MANAGER_CLASS_NAME =
73             "com.evermind.server.ApplicationServerTransactionManager";
74
75     private static final String JavaDoc TRANSACTION_CLASS_NAME =
76             "com.evermind.server.ApplicationServerTransaction";
77
78
79     private Method JavaDoc beginWithNameMethod;
80
81     private Method JavaDoc setTransactionIsolationMethod;
82
83
84     public void afterPropertiesSet() throws TransactionSystemException {
85         super.afterPropertiesSet();
86         loadOC4JTransactionClasses();
87     }
88
89     protected UserTransaction JavaDoc retrieveUserTransaction() throws TransactionSystemException {
90         try {
91             Class JavaDoc transactionUtilityClass = getClass().getClassLoader().loadClass(TRANSACTION_UTILITY_CLASS_NAME);
92             Method JavaDoc getInstanceMethod = transactionUtilityClass.getMethod("getInstance", new Class JavaDoc[0]);
93             Object JavaDoc transactionUtility = getInstanceMethod.invoke(null, new Object JavaDoc[0]);
94             logger.debug("Retrieving JTA UserTransaction from OC4J TransactionUtility");
95             Method JavaDoc getUserTransactionMethod =
96                     transactionUtility.getClass().getMethod("getOC4JUserTransaction", new Class JavaDoc[0]);
97             return (UserTransaction JavaDoc) getUserTransactionMethod.invoke(transactionUtility, new Object JavaDoc[0]);
98         }
99         catch (ClassNotFoundException JavaDoc ex) {
100             logger.debug("Could not find OC4J 10.1.3.2 TransactionUtility: " + ex);
101             // Return null to make the superclass perform its standard J2EE lookup,
102
// which will work on earlier OC4J versions.
103
return null;
104         }
105         catch (InvocationTargetException JavaDoc ex) {
106             throw new TransactionSystemException(
107                     "OC4J's TransactionUtility.getOC4JUserTransaction() method failed", ex.getTargetException());
108         }
109         catch (Exception JavaDoc ex) {
110             throw new TransactionSystemException(
111                     "Could not invoke OC4J's TransactionUtility.getOC4JUserTransaction() method", ex);
112         }
113     }
114
115     private void loadOC4JTransactionClasses() throws TransactionSystemException {
116         try {
117             Class JavaDoc transactionManagerClass = getClass().getClassLoader().loadClass(TRANSACTION_MANAGER_CLASS_NAME);
118             if (transactionManagerClass.isInstance(getUserTransaction())) {
119                 Class JavaDoc transactionClass = getClass().getClassLoader().loadClass(TRANSACTION_CLASS_NAME);
120                 this.beginWithNameMethod = ClassUtils.getMethodIfAvailable(
121                         transactionManagerClass, "begin", new Class JavaDoc[] {String JavaDoc.class});
122                 this.setTransactionIsolationMethod = ClassUtils.getMethodIfAvailable(
123                         transactionClass, "setTransactionIsolation", new Class JavaDoc[] {int.class});
124                 logger.info("Support for OC4J transaction names and isolation levels available");
125             }
126             else {
127                 logger.info("Support for OC4J transaction names and isolation levels not available");
128             }
129         }
130         catch (Exception JavaDoc ex) {
131             throw new TransactionSystemException(
132                     "Could not initialize OC4JJtaTransactionManager because OC4J API classes are not available", ex);
133         }
134     }
135
136
137     protected void doJtaBegin(JtaTransactionObject txObject, TransactionDefinition definition)
138             throws NotSupportedException JavaDoc, SystemException JavaDoc {
139
140         int timeout = determineTimeout(definition);
141         applyTimeout(txObject, timeout);
142
143         // Apply transaction name, if any, through the extended OC4J transaction begin method.
144
if (this.beginWithNameMethod != null && definition.getName() != null) {
145             /*
146             com.evermind.server.ApplicationServerTransactionManager out =
147                     (com.evermind.server.ApplicationServerTransactionManager) ut;
148             out.begin(definition.getName());
149             */

150             try {
151                 this.beginWithNameMethod.invoke(txObject.getUserTransaction(), new Object JavaDoc[] {definition.getName()});
152             }
153             catch (InvocationTargetException JavaDoc ex) {
154                 throw new TransactionSystemException(
155                         "OC4J's UserTransaction.begin(String) method failed", ex.getTargetException());
156             }
157             catch (Exception JavaDoc ex) {
158                 throw new TransactionSystemException(
159                         "Could not invoke OC4J's UserTransaction.begin(String) method", ex);
160             }
161         }
162         else {
163             // No OC4J UserTransaction available or no transaction name specified
164
// -> standard JTA begin call.
165
txObject.getUserTransaction().begin();
166         }
167
168         // Specify isolation level, if any, through the corresponding OC4J transaction method.
169
if (this.setTransactionIsolationMethod != null) {
170             if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
171                 try {
172                     Transaction JavaDoc tx = getTransactionManager().getTransaction();
173                     /*
174                     com.evermind.server.ApplicationServerTransaction otx =
175                             (com.evermind.server.ApplicationServerTransaction) tx;
176                     otx.setTransactionIsolation(definition.getIsolationLevel());
177                     */

178                     Integer JavaDoc isolationLevel = new Integer JavaDoc(definition.getIsolationLevel());
179                     this.setTransactionIsolationMethod.invoke(tx, new Object JavaDoc[] {isolationLevel});
180                 }
181                 catch (InvocationTargetException JavaDoc ex) {
182                     throw new TransactionSystemException(
183                             "OC4J's Transaction.setTransactionIsolation(int) method failed", ex.getTargetException());
184                 }
185                 catch (Exception JavaDoc ex) {
186                     throw new TransactionSystemException(
187                             "Could not invoke OC4J's Transaction.setTransactionIsolation(int) method", ex);
188                 }
189             }
190         }
191         else {
192             applyIsolationLevel(txObject, definition.getIsolationLevel());
193         }
194     }
195
196 }
197
Popular Tags