1 package org.apache.ojb.odmg; 2 3 17 18 import org.apache.ojb.broker.OJBRuntimeException; 19 import org.apache.ojb.broker.util.configuration.Configuration; 20 import org.apache.ojb.broker.util.logging.Logger; 21 import org.apache.ojb.broker.util.logging.LoggerFactory; 22 import org.apache.ojb.broker.transaction.tm.TransactionManagerFactoryException; 23 import org.apache.ojb.broker.transaction.tm.TransactionManagerFactoryFactory; 24 import org.apache.commons.lang.SystemUtils; 25 import org.odmg.TransactionNotInProgressException; 26 27 import javax.transaction.Status ; 28 import javax.transaction.SystemException ; 29 import javax.transaction.Transaction ; 30 import javax.transaction.TransactionManager ; 31 import java.lang.ref.WeakReference ; 32 33 41 public class JTATxManager implements OJBTxManager 42 { 43 private Logger log = LoggerFactory.getLogger(JTATxManager.class); 44 private static ThreadLocal txRepository = new ThreadLocal (); 45 46 50 public void deregisterTx(Object transaction) 51 { 52 txRepository.set(null); 58 } 59 60 public void registerTx(TransactionImpl odmgTrans) 61 { 62 if (log.isDebugEnabled()) log.debug("registerSynchronization was called"); 63 Transaction transaction = null; 64 try 65 { 66 transaction = getJTATransaction(); 67 } 68 catch (SystemException e) 69 { 70 log.error("Obtain current transaction from container failed", e); 71 } 72 if (transaction == null) 73 { 74 log.error("Cannot get the external transaction from the external TM"); 75 throw new TransactionNotInProgressException("No external transaction found"); 76 } 77 if (log.isDebugEnabled()) 78 { 79 log.debug("registerSynchronization was called with parameters" 80 + SystemUtils.LINE_SEPARATOR +"J2EETransactionImpl: " + odmgTrans 81 + SystemUtils.LINE_SEPARATOR + "Transaction: " + transaction); 82 } 83 registerSynchronization(odmgTrans, transaction); 84 } 85 86 89 private void registerSynchronization(TransactionImpl odmgTrans, Transaction transaction) 90 { 91 if (odmgTrans == null || transaction == null) 93 { 94 log.error("One of the given parameters was null --> cannot do synchronization!" + 95 " omdg transaction was null: " + (odmgTrans == null) + 96 ", external transaction was null: " + (transaction == null)); 97 return; 98 } 99 100 int status = -1; try 102 { 103 status = transaction.getStatus(); 104 if (status != Status.STATUS_ACTIVE) 105 { 106 throw new OJBRuntimeException( 107 "Transaction synchronization failed - wrong status of external container tx: " + 108 getStatusString(status)); 109 } 110 } 111 catch (SystemException e) 112 { 113 throw new OJBRuntimeException("Can't read status of external tx", e); 114 } 115 116 try 117 { 118 transaction.registerSynchronization((J2EETransactionImpl) odmgTrans); 121 txRepository.set(new TxBuffer(odmgTrans, transaction)); 124 } 125 catch (Exception e) 126 { 127 log.error("Cannot associate PersistenceBroker with running Transaction", e); 128 throw new OJBRuntimeException( 129 "Transaction synchronization failed - wrong status of external container tx", e); 130 } 131 } 132 133 private static String getStatusString(int status) 134 { 135 switch (status) 136 { 137 case Status.STATUS_ACTIVE: 138 return "STATUS_ACTIVE"; 139 case Status.STATUS_COMMITTED: 140 return "STATUS_COMMITTED"; 141 case Status.STATUS_COMMITTING: 142 return "STATUS_COMMITTING"; 143 case Status.STATUS_MARKED_ROLLBACK: 144 return "STATUS_MARKED_ROLLBACK"; 145 case Status.STATUS_NO_TRANSACTION: 146 return "STATUS_NO_TRANSACTION"; 147 case Status.STATUS_PREPARED: 148 return "STATUS_PREPARED"; 149 case Status.STATUS_PREPARING: 150 return "STATUS_PREPARING"; 151 case Status.STATUS_ROLLEDBACK: 152 return "STATUS_ROLLEDBACK"; 153 case Status.STATUS_ROLLING_BACK: 154 return "STATUS_ROLLING_BACK"; 155 case Status.STATUS_UNKNOWN: 156 return "STATUS_UNKNOWN"; 157 default: 158 return "NO STATUS FOUND"; 159 } 160 } 161 162 165 private TransactionManager getTransactionManager() 166 { 167 TransactionManager retval = null; 168 try 169 { 170 if (log.isDebugEnabled()) log.debug("getTransactionManager called"); 171 retval = TransactionManagerFactoryFactory.instance().getTransactionManager(); 172 } 173 catch (TransactionManagerFactoryException e) 174 { 175 log.warn("Exception trying to obtain TransactionManager from Factory", e); 176 e.printStackTrace(); 177 } 178 return retval; 179 } 180 181 public Transaction getJTATransaction() throws SystemException 182 { 183 if (log.isDebugEnabled()) log.debug("getTransaction called"); 184 if (getTransactionManager() == null) 185 { 186 log.warn("TransactionManager was null"); 187 return null; 188 } 189 return getTransactionManager().getTransaction(); 190 } 191 192 196 public TransactionImpl getCurrentTransaction() 197 { 198 TransactionImpl retval = getTransaction(); 199 if (null == retval) 200 { 201 throw new TransactionNotInProgressException( 202 "Calling method needed transaction, but no transaction found via TransactionManager"); 203 } 204 return retval; 205 } 206 207 211 public TransactionImpl getTransaction() 212 { 213 TxBuffer buf = (TxBuffer) txRepository.get(); 214 return buf != null ? buf.getInternTx() : null; 215 } 216 217 220 public void abortExternalTx(TransactionImpl odmgTrans) 221 { 222 if (log.isDebugEnabled()) log.debug("abortExternTransaction was called"); 223 if (odmgTrans == null) return; 224 TxBuffer buf = (TxBuffer) txRepository.get(); 225 Transaction extTx = buf != null ? buf.getExternTx() : null; 226 try 227 { 228 if (extTx != null && extTx.getStatus() == Status.STATUS_ACTIVE) 229 { 230 if(log.isDebugEnabled()) 231 { 232 log.debug("Set extern transaction to rollback"); 233 } 234 extTx.setRollbackOnly(); 235 } 236 } 237 catch (Exception ignore) 238 { 239 } 240 txRepository.set(null); 241 } 242 243 public void configure(Configuration config) 244 { 245 248 } 249 250 251 private static final class TxBuffer 255 { 256 private WeakReference externTx = null; 257 private WeakReference internTx = null; 258 259 public TxBuffer() 260 { 261 } 262 263 268 269 public TxBuffer(TransactionImpl internTx, Transaction externTx) 270 { 271 this.internTx = new WeakReference (internTx); 272 this.externTx = new WeakReference (externTx); 273 } 274 275 public Transaction getExternTx() 276 { 277 return (Transaction ) externTx.get(); 278 } 279 280 public void setExternTx(Transaction externTx) 281 { 282 this.externTx = new WeakReference (externTx); 283 } 284 285 public TransactionImpl getInternTx() 286 { 287 return (TransactionImpl) internTx.get(); 288 } 289 290 public void setInternTx(TransactionImpl internTx) 291 { 292 this.internTx = new WeakReference (internTx); 293 } 294 } 295 } 296 | Popular Tags |