Author: djencks
Date: Thu Aug 19 17:46:46 2010
New Revision: 987247

URL: http://svn.apache.org/viewvc?rev=987247&view=rev
Log:
OPENEJB-1164 tx for singleton @PreDestroy/@PostConstruct methods. Derived 
partly from patch by Gurkan

Modified:
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java?rev=987247&r1=987246&r2=987247&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java
 Thu Aug 19 17:46:46 2010
@@ -53,6 +53,8 @@ import org.apache.openejb.core.intercept
 import org.apache.openejb.core.interceptor.InterceptorStack;
 import org.apache.openejb.core.ivm.EjbHomeProxyHandler;
 import org.apache.openejb.core.timer.EjbTimerService;
+import org.apache.openejb.core.transaction.EjbTransactionUtil;
+import org.apache.openejb.core.transaction.TransactionPolicy;
 import org.apache.openejb.core.transaction.TransactionPolicyFactory;
 import org.apache.openejb.core.transaction.TransactionType;
 import org.apache.openejb.util.Duration;
@@ -704,6 +706,7 @@ public class CoreDeploymentInfo extends 
     }
 
     public void setCallbackInterceptors(List<InterceptorData> 
callbackInterceptors) {
+        //TODO shouldn't we remove the old callbackInterceptors from 
instanceScopedInterceptors before adding the new ones?
         this.callbackInterceptors.clear();
         this.callbackInterceptors.addAll(callbackInterceptors);
         this.instanceScopedInterceptors.addAll(callbackInterceptors);
@@ -1090,11 +1093,38 @@ public class CoreDeploymentInfo extends 
             callContext.setCurrentOperation(Operation.POST_CONSTRUCT);
             final List<InterceptorData> callbackInterceptors = 
this.getCallbackInterceptors();
             final InterceptorStack postConstruct = new InterceptorStack(bean, 
null, Operation.POST_CONSTRUCT, callbackInterceptors, interceptorInstances);
-            postConstruct.invoke();
+            
+            //Transaction Demarcation for Singleton PostConstruct method
+            TransactionType transactionType;
+
+            if (getComponentType() == BeanType.SINGLETON) {
+                List<Method> callbacks = 
callbackInterceptors.get(callbackInterceptors.size() -1).getPostConstruct();
+                if (callbacks.isEmpty()) {
+                    transactionType = TransactionType.RequiresNew;
+                } else {
+                    transactionType = getTransactionType(callbacks.get(0));
+                    if (transactionType == TransactionType.Required) {
+                        transactionType = TransactionType.RequiresNew;
+                    }
+                }
+            } else {
+                transactionType = isBeanManagedTransaction()? 
TransactionType.BeanManaged: TransactionType.NotSupported;
+            }
+            TransactionPolicy transactionPolicy = 
EjbTransactionUtil.createTransactionPolicy(transactionType, callContext);
+            try{
+                //Call the chain
+                postConstruct.invoke();                
+            } catch(Throwable e) {
+                //RollBack Transaction
+                EjbTransactionUtil.handleSystemException(transactionPolicy, e, 
callContext);
+            }
+            finally{
+                EjbTransactionUtil.afterInvoke(transactionPolicy, callContext);
+            }
 
             return new InstanceContext(this, bean, interceptorInstances);
         } finally {
             ThreadContext.exit(oldContext);
-        }
+        }                        
     }
 }

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java?rev=987247&r1=987246&r2=987247&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java
 Thu Aug 19 17:46:46 2010
@@ -41,8 +41,10 @@ import javax.xml.ws.WebServiceContext;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
 
+import org.apache.openejb.BeanType;
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.ApplicationException;
+import org.apache.openejb.core.transaction.TransactionType;
 import org.apache.openejb.monitoring.StatsInterceptor;
 import org.apache.openejb.monitoring.ObjectNameBuilder;
 import org.apache.openejb.monitoring.ManagedMBean;
@@ -52,6 +54,8 @@ import org.apache.openejb.core.ThreadCon
 import org.apache.openejb.core.InstanceContext;
 import org.apache.openejb.core.interceptor.InterceptorData;
 import org.apache.openejb.core.interceptor.InterceptorStack;
+import org.apache.openejb.core.transaction.EjbTransactionUtil;
+import org.apache.openejb.core.transaction.TransactionPolicy;
 import org.apache.openejb.spi.SecurityService;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
@@ -189,13 +193,39 @@ public class SingletonInstanceManager {
             List<InterceptorData> callbackInterceptors = 
deploymentInfo.getCallbackInterceptors();
             InterceptorStack interceptorStack = new 
InterceptorStack(instance.bean, remove, Operation.PRE_DESTROY, 
callbackInterceptors, instance.interceptors);
 
-            interceptorStack.invoke();
+            //Transaction Demarcation for Singleton PostConstruct method
+            TransactionType transactionType;
+
+            if (deploymentInfo.getComponentType() == BeanType.SINGLETON) {
+                List<Method> callbacks = 
callbackInterceptors.get(callbackInterceptors.size() -1).getPreDestroy();
+                if (callbacks.isEmpty()) {
+                    transactionType = TransactionType.RequiresNew;
+                } else {
+                    transactionType = 
deploymentInfo.getTransactionType(callbacks.get(0));
+                    if (transactionType == TransactionType.Required) {
+                        transactionType = TransactionType.RequiresNew;
+                    }
+                }
+            } else {
+                transactionType = deploymentInfo.isBeanManagedTransaction()? 
TransactionType.BeanManaged: TransactionType.NotSupported;
+            }
+            TransactionPolicy transactionPolicy = 
EjbTransactionUtil.createTransactionPolicy(transactionType, callContext);
+            try{
+                //Call the chain
+                interceptorStack.invoke();                
+            } catch(Throwable e) {
+                //RollBack Transaction
+                EjbTransactionUtil.handleSystemException(transactionPolicy, e, 
callContext);
+            }
+            finally{
+                EjbTransactionUtil.afterInvoke(transactionPolicy, callContext);
+            }
+
         } catch (Throwable re) {
             logger.error("Singleton shutdown failed: 
"+deploymentInfo.getDeploymentID(), re);
         }
-
     }
-
+    
     /**
      * This method has no work to do as all instances are removed from
      * the pool on getInstance(...) and not returned via poolInstance(...)


Reply via email to