001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.openejb.core.transaction;
017:
018: import org.apache.openejb.ApplicationException;
019: import org.apache.openejb.SystemException;
020:
021: import javax.transaction.Status;
022:
023: /**
024: * 17.6.2.4 RequiresNew
025: *
026: * The Container must invoke an enterprise Bean method whose transaction
027: * attribute is set to RequiresNew with a new transaction context.
028: *
029: * If the client invokes the enterprise BeanŐs method while the client is not
030: * associated with a transaction context, the container automatically starts a
031: * new transaction before delegating a method call to the enterprise Bean
032: * business method. The Container automatically enlists all the resource
033: * managers accessed by the business method with the transaction. If the
034: * business method invokes other enterprise beans, the Container passes the
035: * transaction context with the invocation. The Container attempts to commit
036: * the transaction when the business method has completed. The container
037: * performs the commit protocol before the method result is sent to the client.
038: *
039: * If a client calls with a transaction context, the container suspends the
040: * association of the transaction context with the current thread before
041: * starting the new transaction and invoking the business method. The container
042: * resumes the suspended transaction association after the business method and
043: * the new transaction have been completed.
044: *
045: */
046: public class TxRequiresNew extends TransactionPolicy {
047:
048: public TxRequiresNew(TransactionContainer container) {
049: super (Type.RequiresNew, container);
050: }
051:
052: public void beforeInvoke(Object instance, TransactionContext context)
053: throws SystemException, ApplicationException {
054:
055: try {
056:
057: context.clientTx = suspendTransaction(context);
058: beginTransaction(context);
059: context.currentTx = context.getTransactionManager()
060: .getTransaction();
061:
062: } catch (javax.transaction.SystemException se) {
063: throw new SystemException(se);
064: }
065:
066: }
067:
068: public void afterInvoke(Object instance, TransactionContext context)
069: throws ApplicationException, SystemException {
070:
071: try {
072:
073: if (context.currentTx.getStatus() == Status.STATUS_ACTIVE) {
074: commitTransaction(context, context.currentTx);
075: } else {
076: rollbackTransaction(context, context.currentTx);
077: }
078:
079: } catch (javax.transaction.SystemException se) {
080: throw new SystemException(se);
081: } finally {
082: if (context.clientTx != null) {
083: resumeTransaction(context, context.clientTx);
084: } else if (txLogger.isInfoEnabled()) {
085: txLogger.info("TX " + policyToString()
086: + ": No transaction to resume");
087: }
088: }
089: }
090:
091: public void handleApplicationException(Throwable appException,
092: boolean rollback, TransactionContext context)
093: throws ApplicationException, SystemException {
094: if (rollback && context.currentTx != null)
095: markTxRollbackOnly(context.currentTx);
096:
097: throw new ApplicationException(appException);
098: }
099:
100: public void handleSystemException(Throwable sysException,
101: Object instance, TransactionContext context)
102: throws ApplicationException, SystemException {
103:
104: /* [1] Log the system exception or error **********/
105: logSystemException(sysException, context);
106:
107: /* [2] afterInvoke will roll back the tx */
108: markTxRollbackOnly(context.currentTx);
109:
110: /* [3] Discard instance. **************************/
111: discardBeanInstance(instance, context.callContext);
112:
113: /* [4] Throw RemoteException to client ************/
114: throwExceptionToServer(sysException);
115:
116: }
117: }
|