1 16 17 package org.springframework.transaction.jta; 18 19 import java.io.Serializable ; 20 import java.lang.reflect.InvocationTargetException ; 21 import java.lang.reflect.Method ; 22 23 import javax.transaction.InvalidTransactionException ; 24 import javax.transaction.NotSupportedException ; 25 import javax.transaction.SystemException ; 26 import javax.transaction.Transaction ; 27 import javax.transaction.TransactionManager ; 28 import javax.transaction.UserTransaction ; 29 30 import org.springframework.transaction.TransactionDefinition; 31 import org.springframework.transaction.TransactionSystemException; 32 33 74 public class WebLogicJtaTransactionManager extends JtaTransactionManager { 75 76 private static final String USER_TRANSACTION_CLASS_NAME = "weblogic.transaction.UserTransaction"; 77 78 private static final String CLIENT_TRANSACTION_MANAGER_CLASS_NAME = "weblogic.transaction.ClientTransactionManager"; 79 80 private static final String TRANSACTION_MANAGER_CLASS_NAME = "weblogic.transaction.TransactionManager"; 81 82 private static final String TRANSACTION_CLASS_NAME = "weblogic.transaction.Transaction"; 83 84 private static final String TRANSACTION_HELPER_CLASS_NAME = "weblogic.transaction.TransactionHelper"; 85 86 private static final String TX_HELPER_CLASS_NAME = "weblogic.transaction.TxHelper"; 87 88 private static final String ISOLATION_LEVEL_KEY = "ISOLATION LEVEL"; 89 90 91 private boolean weblogicUserTransactionAvailable; 92 93 private Method beginWithNameMethod; 94 95 private Method beginWithNameAndTimeoutMethod; 96 97 private boolean weblogicTransactionManagerAvailable; 98 99 private Method forceResumeMethod; 100 101 private Method setPropertyMethod; 102 103 private Class transactionHelperClass; 104 105 private Object transactionHelper; 106 107 108 public void afterPropertiesSet() throws TransactionSystemException { 109 super.afterPropertiesSet(); 110 loadWebLogicTransactionClasses(); 111 } 112 113 protected UserTransaction retrieveUserTransaction() throws TransactionSystemException { 114 loadWebLogicTransactionHelperClass(); 115 try { 116 logger.debug("Retrieving JTA UserTransaction from WebLogic TransactionHelper/TxHelper"); 117 Method getUserTransactionMethod = 118 this.transactionHelperClass.getMethod("getUserTransaction", new Class [0]); 119 return (UserTransaction ) getUserTransactionMethod.invoke(this.transactionHelper, new Object [0]); 120 } 121 catch (InvocationTargetException ex) { 122 throw new TransactionSystemException( 123 "WebLogic's TransactionHelper/TxHelper.getUserTransaction() method failed", ex.getTargetException()); 124 } 125 catch (Exception ex) { 126 throw new TransactionSystemException( 127 "Could not invoke WebLogic's TransactionHelper/TxHelper.getUserTransaction() method", ex); 128 } 129 } 130 131 protected TransactionManager retrieveTransactionManager() throws TransactionSystemException { 132 loadWebLogicTransactionHelperClass(); 133 try { 134 logger.debug("Retrieving JTA TransactionManager from WebLogic TransactionHelper/TxHelper"); 135 Method getTransactionManagerMethod = 136 this.transactionHelperClass.getMethod("getTransactionManager", new Class [0]); 137 return (TransactionManager ) getTransactionManagerMethod.invoke(this.transactionHelper, new Object [0]); 138 } 139 catch (InvocationTargetException ex) { 140 throw new TransactionSystemException( 141 "WebLogic's TransactionHelper/TxHelper.getTransactionManager() method failed", ex.getTargetException()); 142 } 143 catch (Exception ex) { 144 throw new TransactionSystemException( 145 "Could not invoke WebLogic's TransactionHelper/TxHelper.getTransactionManager() method", ex); 146 } 147 } 148 149 150 private void loadWebLogicTransactionHelperClass() throws TransactionSystemException { 151 if (this.transactionHelperClass == null) { 152 try { 153 try { 154 this.transactionHelperClass = 155 getClass().getClassLoader().loadClass(TRANSACTION_HELPER_CLASS_NAME); 156 Method getTransactionHelperMethod = 157 this.transactionHelperClass.getMethod("getTransactionHelper", new Class [0]); 158 this.transactionHelper = getTransactionHelperMethod.invoke(null, new Object [0]); 159 logger.debug("WebLogic 8.1+ TransactionHelper found"); 160 } 161 catch (ClassNotFoundException ex) { 162 this.transactionHelperClass = 163 getClass().getClassLoader().loadClass(TX_HELPER_CLASS_NAME); 164 logger.debug("WebLogic 7.0 TxHelper found"); 165 } 166 } 167 catch (InvocationTargetException ex) { 168 throw new TransactionSystemException( 169 "WebLogic's TransactionHelper.getTransactionHelper() method failed", ex.getTargetException()); 170 } 171 catch (Exception ex) { 172 throw new TransactionSystemException( 173 "Could not initialize WebLogicJtaTransactionManager because WebLogic API classes are not available", 174 ex); 175 } 176 } 177 } 178 179 private void loadWebLogicTransactionClasses() throws TransactionSystemException { 180 try { 181 Class userTransactionClass = 182 getClass().getClassLoader().loadClass(USER_TRANSACTION_CLASS_NAME); 183 this.weblogicUserTransactionAvailable = 184 userTransactionClass.isInstance(getUserTransaction()); 185 if (this.weblogicUserTransactionAvailable) { 186 this.beginWithNameMethod = 187 userTransactionClass.getMethod("begin", new Class [] {String .class}); 188 this.beginWithNameAndTimeoutMethod = 189 userTransactionClass.getMethod("begin", new Class [] {String .class, int.class}); 190 logger.info("Support for WebLogic transaction names available"); 191 } 192 else { 193 logger.info("Support for WebLogic transaction names not available"); 194 } 195 196 Class transactionManagerClass = null; 197 try { 198 transactionManagerClass = 200 getClass().getClassLoader().loadClass(CLIENT_TRANSACTION_MANAGER_CLASS_NAME); 201 logger.debug("WebLogic 8.1+ ClientTransactionManager found"); 202 } 203 catch (ClassNotFoundException ex) { 204 transactionManagerClass = 206 getClass().getClassLoader().loadClass(TRANSACTION_MANAGER_CLASS_NAME); 207 logger.debug("WebLogic 7.0 TransactionManager found"); 208 } 209 210 this.weblogicTransactionManagerAvailable = 211 transactionManagerClass.isInstance(getTransactionManager()); 212 if (this.weblogicTransactionManagerAvailable) { 213 Class transactionClass = getClass().getClassLoader().loadClass(TRANSACTION_CLASS_NAME); 214 this.forceResumeMethod = 215 transactionManagerClass.getMethod("forceResume", new Class [] {Transaction .class}); 216 this.setPropertyMethod = 217 transactionClass.getMethod("setProperty", new Class [] {String .class, Serializable .class}); 218 logger.debug("Support for WebLogic forceResume available"); 219 } 220 else { 221 logger.warn("Support for WebLogic forceResume not available"); 222 } 223 } 224 catch (Exception ex) { 225 throw new TransactionSystemException( 226 "Could not initialize WebLogicJtaTransactionManager because WebLogic API classes are not available", 227 ex); 228 } 229 } 230 231 232 protected void doJtaBegin(JtaTransactionObject txObject, TransactionDefinition definition) 233 throws NotSupportedException , SystemException { 234 235 int timeout = determineTimeout(definition); 236 237 if (this.weblogicUserTransactionAvailable && definition.getName() != null) { 239 try { 240 if (timeout > TransactionDefinition.TIMEOUT_DEFAULT) { 241 245 this.beginWithNameAndTimeoutMethod.invoke(txObject.getUserTransaction(), 246 new Object [] {definition.getName(), new Integer (timeout)}); 247 } 248 else { 249 253 this.beginWithNameMethod.invoke(txObject.getUserTransaction(), 254 new Object [] {definition.getName()}); 255 } 256 } 257 catch (InvocationTargetException ex) { 258 throw new TransactionSystemException( 259 "WebLogic's UserTransaction.begin() method failed", ex.getTargetException()); 260 } 261 catch (Exception ex) { 262 throw new TransactionSystemException( 263 "Could not invoke WebLogic's UserTransaction.begin() method", ex); 264 } 265 } 266 else { 267 applyTimeout(txObject, timeout); 270 txObject.getUserTransaction().begin(); 271 } 272 273 if (this.weblogicTransactionManagerAvailable) { 275 if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { 276 try { 277 Transaction tx = getTransactionManager().getTransaction(); 278 Integer isolationLevel = new Integer (definition.getIsolationLevel()); 279 283 this.setPropertyMethod.invoke(tx, new Object [] {ISOLATION_LEVEL_KEY, isolationLevel}); 284 } 285 catch (InvocationTargetException ex) { 286 throw new TransactionSystemException( 287 "WebLogic's Transaction.setProperty(String, Serializable) method failed", ex.getTargetException()); 288 } 289 catch (Exception ex) { 290 throw new TransactionSystemException( 291 "Could not invoke WebLogic's Transaction.setProperty(String, Serializable) method", ex); 292 } 293 } 294 } 295 else { 296 applyIsolationLevel(txObject, definition.getIsolationLevel()); 297 } 298 } 299 300 protected void doJtaResume(JtaTransactionObject txObject, Object suspendedTransaction) 301 throws InvalidTransactionException , SystemException { 302 303 try { 304 getTransactionManager().resume((Transaction ) suspendedTransaction); 305 } 306 catch (InvalidTransactionException ex) { 307 if (!this.weblogicTransactionManagerAvailable) { 308 throw ex; 309 } 310 311 if (logger.isDebugEnabled()) { 312 logger.debug("Standard JTA resume threw InvalidTransactionException: " + ex.getMessage() + 313 " - trying WebLogic JTA forceResume"); 314 } 315 320 try { 321 this.forceResumeMethod.invoke(getTransactionManager(), new Object [] {suspendedTransaction}); 322 } 323 catch (InvocationTargetException ex2) { 324 throw new TransactionSystemException( 325 "WebLogic's TransactionManager.forceResume(Transaction) method failed", ex2.getTargetException()); 326 } 327 catch (Exception ex2) { 328 throw new TransactionSystemException( 329 "Could not access WebLogic's TransactionManager.forceResume(Transaction) method", ex2); 330 } 331 } 332 } 333 334 } 335 | Popular Tags |