private void registerSessionSynchronization(Instance instance, ThreadContext callContext) { TransactionPolicy txPolicy = callContext.getTransactionPolicy(); if (txPolicy == null) { throw new IllegalStateException("ThreadContext does not contain a TransactionEnvironment"); } SessionSynchronizationCoordinator coordinator = (SessionSynchronizationCoordinator) txPolicy.getResource(SessionSynchronizationCoordinator.class); if (coordinator == null) { coordinator = new SessionSynchronizationCoordinator(txPolicy); txPolicy.registerSynchronization(coordinator); txPolicy.putResource(SessionSynchronizationCoordinator.class, coordinator); } // SessionSynchronization are only enabled for beans after CREATE that are not bean-managed and // implement the SessionSynchronization interface boolean synchronize = callContext.getCurrentOperation() != Operation.CREATE && callContext.getBeanContext().isSessionSynchronized() && txPolicy.isTransactionActive(); coordinator.registerSessionSynchronization( instance, callContext.getBeanContext(), callContext.getPrimaryKey(), synchronize); }
public void beforeCompletion() { for (Synchronization synchronization : registry.values()) { Instance instance = synchronization.instance; // don't call beforeCompletion when transaction is marked rollback only if (txPolicy.isRollbackOnly()) return; // only call beforeCompletion on beans with session synchronization if (!synchronization.isCallSessionSynchronization()) continue; // Invoke beforeCompletion ThreadContext callContext = new ThreadContext( instance.beanContext, instance.primaryKey, Operation.BEFORE_COMPLETION); callContext.setCurrentAllowedStates(null); ThreadContext oldCallContext = ThreadContext.enter(callContext); try { instance.setInUse(true); BeanContext beanContext = instance.beanContext; List<InterceptorData> interceptors = beanContext.getCallbackInterceptors(); InterceptorStack interceptorStack = new InterceptorStack( instance.bean, null, Operation.BEFORE_COMPLETION, interceptors, instance.interceptors); interceptorStack.invoke(); instance.setInUse(false); } catch (InvalidateReferenceException e) { // exception has alredy been handled } catch (Exception e) { String message = "An unexpected system exception occured while invoking the beforeCompletion method on the SessionSynchronization object"; // [1] Log the exception or error logger.error(message, e); // [2] Mark the transaction for rollback. txPolicy.setRollbackOnly(e); // [3] Discard the instance discardInstance(callContext); // [4] throw the java.rmi.RemoteException to the client throw new RuntimeException(message, e); } finally { ThreadContext.exit(oldCallContext); } } }