You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by as...@apache.org on 2012/05/23 10:01:49 UTC

svn commit: r1341771 - /ofbiz/branches/release12.04/framework/service/src/org/ofbiz/service/ServiceUtil.java

Author: ashish
Date: Wed May 23 08:01:48 2012
New Revision: 1341771

URL: http://svn.apache.org/viewvc?rev=1341771&view=rev
Log:
Applied bug fix from trunk r1341770. 
Fixing important bug that we have observed in one of the production system. This error comes when production system generates lot of JobSandbox records. And sometime it happens that purgeOldJobs service tries to remove RuntimeData from the system but runtimeDataId is still referred in JobSandbox records. To fix this bug we have separated out the code for deleting RuntimeData. We have also tested this fix on production system for about two weeks and now things are better over there. Thanks Jacopo for the discussion.

Here I am sharing console log for everyones reference:
f9cb9ec37f8ed14 Apr 28, 2012 10:47:46 PM org.apache.jk.common.ChannelSocket processConnection
f9cb9ec37f8f0fc WARNING: processCallbacks status 2
f9cbcd4388830dc 2012-04-28 23:00:10,947 (default-invoker-Thread-781938) [ GenericDelegator.java:1163:ERROR]
f9cbcd4388834c4 ---- exception report ----------------------------------------------------------
f9cbcd4388838ac Failure in removeByCondition operation for entity [RuntimeData]: org.ofbiz.entity.GenericDataSourceException: Generic Entity Exception occured in deleteByCondition (SQL Exception while executing the following:DELETE FROM public.RUNTIME_DATA WHERE (RUNTIME_DATA_ID = '45794') (ERROR: update or delete on table "runtime_data" violates foreign key constraint "job_sndbx_rntmdta" on table "job_sandbox"
f9cbcd43888d4ec Detail: Key (runtime_data_id)=(45794) is still referenced from table "job_sandbox".)). Rolling back transaction.
f9cbcd43888e48c Exception: org.ofbiz.entity.GenericDataSourceException
f9cbcd43888e874 Message: Generic Entity Exception occured in deleteByCondition (SQL Exception while executing the following:DELETE FROM public.RUNTIME_DATA WHERE (RUNTIME_DATA_ID = '45794') (ERROR: update or delete on table "runtime_data" violates foreign key constraint "job_sndbx_rntmdta" on table "job_sandbox"
f9cbcd43888ffe4 Detail: Key (runtime_data_id)=(45794) is still referenced from table "job_sandbox".))
f9cbcd4388903cc ---- cause ---------------------------------------------------------------------
f9cbcd438890b9c Exception: org.ofbiz.entity.GenericDataSourceException
f9cbcd438890f84 Message: SQL Exception while executing the following:DELETE FROM public.RUNTIME_DATA WHERE (RUNTIME_DATA_ID = '45794') (ERROR: update or delete on table "runtime_data" violates foreign key constraint "job_sndbx_rntmdta" on table "job_sandbox"
f9cbcd43889136c Detail: Key (runtime_data_id)=(45794) is still referenced from table "job_sandbox".)
f9cbcd438895da4 ---- cause ---------------------------------------------------------------------
f9cbcd43889618c Exception: org.postgresql.util.PSQLException
f9cbcd43889618c Message: ERROR: update or delete on table "runtime_data" violates foreign key constraint "job_sndbx_rntmdta" on table "job_sandbox"
f9cbcd438896574 Detail: Key (runtime_data_id)=(45794) is still referenced from table "job_sandbox".
f9cbcd43889712c ---- stack trace ---------------------------------------------------------------
f9cbcd43889712c org.postgresql.util.PSQLException: ERROR: update or delete on table "runtime_data" violates foreign key constraint "job_sndbx_rntmdta" on table "job_sandbox"
f9cbcd43889889c Detail: Key (runtime_data_id)=(45794) is still referenced from table "job_sandbox".
f9cbcd43889889c org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2103)
f9cbcd438898c84 org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1836)
f9cbcd438899454 org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
f9cbcd43889983c org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512)
f9cbcd43889983c org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388)
f9cbcd438899c24 org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:334)
f9cbcd43889a3f4 org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
f9cbcd43889a7dc org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
f9cbcd43889abc4 org.ofbiz.entity.jdbc.SQLProcessor.executeUpdate(SQLProcessor.java:420)
f9cbcd43889abc4 org.ofbiz.entity.datasource.GenericDAO.deleteByCondition(GenericDAO.java:1158)
f9cbcd43889bb64 org.ofbiz.entity.datasource.GenericDAO.deleteByCondition(GenericDAO.java:1132)
f9cbcd43889bf4c org.ofbiz.entity.datasource.GenericHelperDAO.removeByCondition(GenericHelperDAO.java:160)
f9cbcd43889c334 org.ofbiz.entity.GenericDelegator.removeByCondition(GenericDelegator.java:1152)
f9cbcd43889c334 org.ofbiz.entity.GenericDelegator.removeByAnd(GenericDelegator.java:1120)
f9cbcd43889cb04 org.ofbiz.entity.GenericDelegator.removeByAnd(GenericDelegator.java:1105)
f9cbcd43889ceec org.ofbiz.entity.GenericDelegator.removeByAnd(GenericDelegator.java:1098)
f9cbcd43889ceec org.ofbiz.service.ServiceUtil.purgeOldJobs(ServiceUtil.java:476)
f9cbcd43889d2d4 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
f9cbcd43889d2d4 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
f9cbcd43889de8c sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
f9cbcd43889de8c java.lang.reflect.Method.invoke(Method.java:597)
f9cbcd43889e274 org.ofbiz.service.engine.StandardJavaEngine.serviceInvoker(StandardJavaEngine.java:100)
f9cbcd43889e274 org.ofbiz.service.engine.StandardJavaEngine.runSync(StandardJavaEngine.java:57)
f9cbcd43889f5fc org.ofbiz.service.ServiceDispatcher.runSync(ServiceDispatcher.java:396)
f9cbcd43889f9e4 org.ofbiz.service.ServiceDispatcher.runSync(ServiceDispatcher.java:224)
f9cbcd43889f9e4 org.ofbiz.service.GenericDispatcher.runSync(GenericDispatcher.java:163)
f9cbcd43889fdcc org.ofbiz.service.job.GenericServiceJob.exec(GenericServiceJob.java:71)
f9cbcd43889fdcc org.ofbiz.service.job.JobInvoker.run(JobInvoker.java:242)
f9cbcd4388a3c4c java.lang.Thread.run(Thread.java:662)
f9cbcd4388a3c4c --------------------------------------------------------------------------------
f9cbcd4388a4034

Modified:
    ofbiz/branches/release12.04/framework/service/src/org/ofbiz/service/ServiceUtil.java

Modified: ofbiz/branches/release12.04/framework/service/src/org/ofbiz/service/ServiceUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/service/src/org/ofbiz/service/ServiceUtil.java?rev=1341771&r1=1341770&r2=1341771&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/service/src/org/ofbiz/service/ServiceUtil.java (original)
+++ ofbiz/branches/release12.04/framework/service/src/org/ofbiz/service/ServiceUtil.java Wed May 23 08:01:48 2012
@@ -18,6 +18,7 @@
  *******************************************************************************/
 package org.ofbiz.service;
 
+import java.math.BigDecimal;
 import java.sql.Timestamp;
 import com.ibm.icu.util.Calendar;
 import java.util.LinkedList;
@@ -413,13 +414,12 @@ public class ServiceUtil {
                     // begin this transaction
                     beganTx1 = TransactionUtil.begin();
 
-                    EntityListIterator foundJobs = delegator.find("JobSandbox", mainCond, null, null, null, findOptions);
+                    EntityListIterator foundJobs = delegator.find("JobSandbox", mainCond, null, UtilMisc.toSet("jobId"), null, findOptions);
                     try {
                         curList = foundJobs.getPartialList(1, 1000);
                     } finally {
                         foundJobs.close();
                     }
-
                 } catch (GenericEntityException e) {
                     Debug.logError(e, "Cannot obtain job data from datasource", module);
                     try {
@@ -435,20 +435,14 @@ public class ServiceUtil {
                         Debug.logWarning(e, module);
                     }
                 }
-
                 // remove each from the list in its own transaction
                 if (UtilValidate.isNotEmpty(curList)) {
-                    // list of runtime data IDs to attempt to delete
-                    List<String> runtimeToDelete = FastList.newInstance();
-
                     for (GenericValue job: curList) {
-                        String runtimeId = job.getString("runtimeDataId");
                         String jobId = job.getString("jobId");
                         boolean beganTx2 = false;
                         try {
                             beganTx2 = TransactionUtil.begin();
                             job.remove();
-                            runtimeToDelete.add(runtimeId);
                         } catch (GenericEntityException e) {
                             Debug.logInfo("Cannot remove job data for ID: " + jobId, module);
                             try {
@@ -464,37 +458,51 @@ public class ServiceUtil {
                             }
                         }
                     }
-
-                    // delete the runtime data - in a new transaction for each delete
-                    // we do this so that the ones which cannot be deleted to not cause
-                    // the entire group to rollback; some may be attached to multiple jobs.
-                    if (runtimeToDelete.size() > 0) {
-                        for (String runtimeId: runtimeToDelete) {
-                            boolean beganTx3 = false;
-                            try {
-                                beganTx3 = TransactionUtil.begin();
-                                delegator.removeByAnd("RuntimeData", "runtimeDataId", runtimeId);
-
-                            } catch (GenericEntityException e) {
-                                Debug.logInfo("Cannot remove runtime data for ID: " + runtimeId, module);
-                                try {
-                                    TransactionUtil.rollback(beganTx3, e.getMessage(), e);
-                                } catch (GenericTransactionException e1) {
-                                    Debug.logWarning(e1, module);
-                                }
-                            } finally {
-                                try {
-                                    TransactionUtil.commit(beganTx3);
-                                } catch (GenericTransactionException e) {
-                                    Debug.logWarning(e, module);
-                                }
-                            }
-                        }
-                    }
                 } else {
                     noMoreResults = true;
                 }
             }
+            
+            // Now JobSandbox data is cleaned up. Now process Runtime data and remove the whole data in single shot that is of no need.
+            boolean beganTx3 = false;
+            GenericValue runtimeData = null;
+            EntityListIterator runTimeDataIt = null;
+            List<GenericValue> runtimeDataToDelete = FastList.newInstance();
+            long jobsandBoxCount = 0;
+            try {
+                // begin this transaction
+                beganTx3 = TransactionUtil.begin();
+                
+                runTimeDataIt = delegator.find("RuntimeData", null, null, UtilMisc.toSet("runtimeDataId"), null, null);
+                try {
+                    while ((runtimeData = runTimeDataIt.next()) != null) {
+                        EntityCondition whereCondition = EntityCondition.makeCondition(UtilMisc.toList(EntityCondition.makeCondition("runtimeDataId", EntityOperator.NOT_EQUAL, null),
+                                EntityCondition.makeCondition("runtimeDataId", EntityOperator.EQUALS, runtimeData.getString("runtimeDataId"))), EntityOperator.AND);
+                        jobsandBoxCount = delegator.findCountByCondition("JobSandbox", whereCondition, null, null);
+                        if (BigDecimal.ZERO.compareTo(BigDecimal.valueOf(jobsandBoxCount)) == 0) {
+                            runtimeDataToDelete.add(runtimeData);
+                        }
+                    }
+                } finally {
+                    runTimeDataIt.close();
+                }
+                // Now we are ready to delete runtimeData, we can safely delete complete list that we have recently fetched i.e runtimeDataToDelete.
+                delegator.removeAll(runtimeDataToDelete);
+            } catch (GenericEntityException e) {
+                Debug.logError(e, "Cannot obtain runtime data from datasource", module);
+                try {
+                    TransactionUtil.rollback(beganTx3, e.getMessage(), e);
+                } catch (GenericTransactionException e1) {
+                    Debug.logWarning(e1, module);
+                }
+                return ServiceUtil.returnError(e.getMessage());
+            } finally {
+                try {
+                    TransactionUtil.commit(beganTx3);
+                } catch (GenericTransactionException e) {
+                    Debug.logWarning(e, module);
+                }
+            }
         } catch (GenericTransactionException e) {
             Debug.logError(e, "Unable to suspend transaction; cannot purge jobs!", module);
             return ServiceUtil.returnError(e.getMessage());