1 package org.openejb.core.stateful; 2 3 import javax.ejb.EnterpriseBean ; 4 import javax.ejb.SessionSynchronization ; 5 import javax.transaction.Status ; 6 import javax.transaction.Transaction ; 7 import javax.transaction.TransactionManager ; 8 9 import org.openejb.ApplicationException; 10 import org.openejb.OpenEJB; 11 import org.openejb.SystemException; 12 import org.openejb.core.Operations; 13 import org.openejb.core.ThreadContext; 14 import org.openejb.core.transaction.TransactionContext; 15 import org.openejb.util.Logger; 16 17 33 public class SessionSynchronizationCoordinator implements javax.transaction.Synchronization { 34 35 36 private static java.util.HashMap coordinators = new java.util.HashMap (); 37 public static Logger logger = Logger.getInstance( "OpenEJB", "org.openejb.util.resources" ); 38 39 47 private java.util.HashMap sessionSynchronizations = new java.util.HashMap (); 48 49 50 public static void registerSessionSynchronization(SessionSynchronization session, TransactionContext context) throws javax.transaction.SystemException , javax.transaction.RollbackException { 51 SessionSynchronizationCoordinator coordinator = null; 52 53 coordinator = (SessionSynchronizationCoordinator)coordinators.get( context.currentTx ); 54 55 if (coordinator == null) { 56 coordinator = new SessionSynchronizationCoordinator(); 57 try{ 58 context.currentTx.registerSynchronization( coordinator); 59 }catch(Exception e) { 60 logger.error("", e); 62 return; 63 } 64 coordinators.put( context.currentTx, coordinator ); 65 } 66 67 coordinator._registerSessionSynchronization( session, context.callContext ); 68 } 69 70 private void _registerSessionSynchronization(SessionSynchronization session, ThreadContext callContext){ 71 boolean registered = sessionSynchronizations.containsKey( callContext.getPrimaryKey() ); 72 73 if ( registered ) return; 74 75 try{ 76 callContext = (ThreadContext)callContext.clone(); 77 }catch(Exception e) {} 78 sessionSynchronizations.put(callContext.getPrimaryKey(), callContext); 79 80 byte currentOperation = callContext.getCurrentOperation(); 81 callContext.setCurrentOperation(Operations.OP_AFTER_BEGIN); 82 try{ 83 84 session.afterBegin(); 85 86 } catch (Exception e){ 87 String message = "An unexpected system exception occured while invoking the afterBegin method on the SessionSynchronization object: "+e.getClass().getName()+" "+e.getMessage(); 88 logger.error(message, e); 89 throw new RuntimeException ( message ); 90 91 } finally { 92 callContext.setCurrentOperation(currentOperation); 93 } 94 } 95 96 100 public void beforeCompletion() { 101 102 ThreadContext originalContext = ThreadContext.getThreadContext(); 103 104 Object [] contexts = sessionSynchronizations.values().toArray(); 105 106 for(int i = 0; i < contexts.length; i++){ 107 108 ThreadContext callContext = (ThreadContext)contexts[i]; 110 111 ThreadContext.setThreadContext(callContext); 112 StatefulInstanceManager instanceManager = null; 113 114 try{ 115 StatefulContainer container = (StatefulContainer)callContext.getDeploymentInfo().getContainer(); 116 instanceManager = container.getInstanceManager(); 117 121 callContext.setCurrentOperation(Operations.OP_BEFORE_COMPLETION); 122 123 SessionSynchronization bean = (SessionSynchronization )instanceManager.obtainInstance(callContext.getPrimaryKey(), callContext); 124 bean.beforeCompletion(); 125 instanceManager.poolInstance(callContext.getPrimaryKey(), (EnterpriseBean )bean); 126 }catch(org.openejb.InvalidateReferenceException inv) { 127 }catch(Exception e){ 132 139 String message = "An unexpected system exception occured while invoking the beforeCompletion method on the SessionSynchronization object: "+e.getClass().getName()+" "+e.getMessage(); 141 142 143 logger.error( message, e); 144 145 146 Transaction tx = null; 147 try{ 148 tx = getTxMngr().getTransaction(); 149 } catch (Throwable t){ 150 logger.error("Could not retreive the current transaction from the transaction manager while handling a callback exception from the beforeCompletion method of bean "+callContext.getPrimaryKey()); 151 } 152 try{ 153 markTxRollbackOnly( tx ); 154 } catch (Throwable t){ 155 logger.error("Could not mark the current transaction for rollback while handling a callback exception from the beforeCompletion method of bean "+callContext.getPrimaryKey()); 156 } 157 158 159 discardInstance( instanceManager, callContext ); 160 161 162 throw new RuntimeException ( message ); 163 } finally { 164 ThreadContext.setThreadContext( originalContext ); 165 } 166 } 167 } 168 169 175 public void afterCompletion(int status) { 176 177 ThreadContext originalContext = ThreadContext.getThreadContext(); 178 179 Object [] contexts = sessionSynchronizations.values().toArray(); 180 181 try{ 182 Transaction tx = getTxMngr().getTransaction(); 183 coordinators.remove( tx ); 184 }catch(Exception e) { 185 logger.error("", e); 186 } 187 for(int i = 0; i < contexts.length; i++){ 188 189 ThreadContext callContext = (ThreadContext)contexts[i]; 191 192 ThreadContext.setThreadContext(callContext); 193 StatefulInstanceManager instanceManager = null; 194 195 try{ 196 StatefulContainer container = (StatefulContainer)callContext.getDeploymentInfo().getContainer(); 197 instanceManager = container.getInstanceManager(); 198 202 callContext.setCurrentOperation(Operations.OP_AFTER_COMPLETION); 203 204 SessionSynchronization bean = (SessionSynchronization )instanceManager.obtainInstance(callContext.getPrimaryKey(), callContext); 205 206 bean.afterCompletion( status == Status.STATUS_COMMITTED ); 207 instanceManager.poolInstance(callContext.getPrimaryKey(), (EnterpriseBean )bean); 208 }catch(org.openejb.InvalidateReferenceException inv) { 209 }catch(Exception e){ 214 String message = "An unexpected system exception occured while invoking the afterCompletion method on the SessionSynchronization object: "+e.getClass().getName()+" "+e.getMessage(); 216 217 218 logger.error( message, e); 219 220 221 Transaction tx = null; 222 try{ 223 tx = getTxMngr().getTransaction(); 224 } catch (Throwable t){ 225 logger.error("Could not retreive the current transaction from the transaction manager while handling a callback exception from the afterCompletion method of bean "+callContext.getPrimaryKey()); 226 } 227 try{ 228 markTxRollbackOnly( tx ); 229 } catch (Throwable t){ 230 logger.error("Could not mark the current transaction for rollback while handling a callback exception from the afterCompletion method of bean "+callContext.getPrimaryKey()); 231 } 232 233 234 discardInstance( instanceManager, callContext ); 235 236 237 throw new RuntimeException ( message ); 239 } finally { 240 ThreadContext.setThreadContext( originalContext ); 241 } 242 } 243 } 244 245 protected void discardInstance(StatefulInstanceManager instanceManager, ThreadContext callContext){ 246 try{ 247 instanceManager.freeInstance( callContext.getPrimaryKey() ); 248 }catch(org.openejb.OpenEJBException oee){ 249 } 251 } 252 253 protected void markTxRollbackOnly( Transaction tx ) throws SystemException{ 254 try { 255 if ( tx != null ) tx.setRollbackOnly(); 256 } catch ( javax.transaction.SystemException se ) { 257 throw new org.openejb.SystemException(se); 258 } 259 } 260 261 protected TransactionManager getTxMngr( ) { 262 return OpenEJB.getTransactionManager(); 263 } 264 265 271 protected void throwExceptionToServer( Throwable sysException ) throws ApplicationException{ 272 274 throw new ApplicationException( sysException ); 276 277 279 } 280 } 281 | Popular Tags |