details:   /erp/devel/pi/rev/224a5ad97e53
changeset: 10398:224a5ad97e53
user:      Stefan Hühner <stefan.huehner <at> openbravo.com>
date:      Mon Feb 07 14:08:52 2011 +0100
summary:   Avoid locking issues in db in FIC by doing flush&commit before 
calling callouts
In FIC flush/commit durrent dal-transaction to release any db-locks acquired by
dal-usage in FIC which interfers badly with callouts which run in a seperate
jdbc connection/transaction.
Example problem: ad_sequence usage in FIC and open of sales invoice window
Note issue only happens if current dal-flush/commit in HSAS is removed (done by
following commit)

details:   /erp/devel/pi/rev/5cd9e415371e
changeset: 10399:5cd9e415371e
user:      Stefan Hühner <stefan.huehner <at> openbravo.com>
date:      Mon Feb 07 14:22:54 2011 +0100
summary:   Remove implicit dal-connection commit from UsageAudit call in HSAS.
part of the HSAS service method does an insert into the ad_session_usage_audit
table (if usage audit is enabled). That was done using the currently active
dal-connection and has an explicit dal-flush/-commit after it.
That impacts (at least) performance of callout-execution in FIC badly, as it
does an implicit flush/commit after each callout execution.

This change moves the the insert into an new jdbc connection/transaction which
is committed directly.

Note: that does change behavior slightly as before at the end of the service
method, called just before the real servlet for each request, a dal-commit was
done and now this is reverted. However potentially affected only include HSAS
itself & the pluggable authentication managers.

diffstat:

 
modules/org.openbravo.client.application/src/org/openbravo/client/application/window/FormInitializationComponent.java
 |  10 ++
 src/org/openbravo/base/secureApp/HttpSecureAppServlet.java                     
                                       |   2 +-
 src/org/openbravo/erpCommon/security/SessionLogin_data.xsql                    
                                       |  25 +++++-
 src/org/openbravo/erpCommon/security/UsageAudit.java                           
                                       |  48 +++++++++-
 4 files changed, 82 insertions(+), 3 deletions(-)

diffs (160 lines):

diff -r ece41d561ffe -r 5cd9e415371e 
modules/org.openbravo.client.application/src/org/openbravo/client/application/window/FormInitializationComponent.java
--- 
a/modules/org.openbravo.client.application/src/org/openbravo/client/application/window/FormInitializationComponent.java
     Mon Feb 07 13:48:27 2011 +0100
+++ 
b/modules/org.openbravo.client.application/src/org/openbravo/client/application/window/FormInitializationComponent.java
     Mon Feb 07 14:22:54 2011 +0100
@@ -21,6 +21,7 @@
 import java.lang.reflect.Method;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
+import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -701,6 +702,15 @@
       List<String> calledCallouts, List<String> calloutsToCall, List<String> 
lastfieldChangedList,
       List<String> messages, List<String> dynamicCols) {
 
+    // flush&commit to release lock in db which otherwise interfere with 
callouts which run in their
+    // own jdbc connection (i.e. lock on AD_Sequence when using with Sales 
Invoice window)
+    OBDal.getInstance().flush();
+    try {
+      OBDal.getInstance().getConnection().commit();
+    } catch (SQLException e1) {
+      throw new OBException("Error committing before runnings callouts", e1);
+    }
+
     List<Field> fields = tab.getADFieldList();
     HashMap<String, Field> inpFields = buildInpField(fields);
     boolean comboReloadNeeded = false;
diff -r ece41d561ffe -r 5cd9e415371e 
src/org/openbravo/base/secureApp/HttpSecureAppServlet.java
--- a/src/org/openbravo/base/secureApp/HttpSecureAppServlet.java        Mon Feb 
07 13:48:27 2011 +0100
+++ b/src/org/openbravo/base/secureApp/HttpSecureAppServlet.java        Mon Feb 
07 14:22:54 2011 +0100
@@ -400,7 +400,7 @@
           SessionInfo.setModuleId(classInfo.adModuleId);
         }
 
-        UsageAudit.auditAction(vars1, this.getClass().getName());
+        UsageAudit.auditActionNoDal(this, vars1, this.getClass().getName());
 
         // Autosave logic
         final Boolean saveRequest = (Boolean) request.getAttribute("autosave");
diff -r ece41d561ffe -r 5cd9e415371e 
src/org/openbravo/erpCommon/security/SessionLogin_data.xsql
--- a/src/org/openbravo/erpCommon/security/SessionLogin_data.xsql       Mon Feb 
07 13:48:27 2011 +0100
+++ b/src/org/openbravo/erpCommon/security/SessionLogin_data.xsql       Mon Feb 
07 14:22:54 2011 +0100
@@ -12,7 +12,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2001-2010 Openbravo SLU 
+ * All portions are Copyright (C) 2001-2011 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -70,4 +70,27 @@
     ]]></Sql>
   </SqlMethod>
   
+  <SqlMethod name="isUsageAuditEnabled" type="preparedStatement" 
return="boolean">
+    <Sql><![CDATA[
+        SELECT isusageauditenabled
+          FROM AD_SYSTEM_INFO
+    ]]></Sql>
+  </SqlMethod>
+
+  <SqlMethod name="insertUsageAudit" type="preparedStatement" 
return="rowCount" connection="true" >
+    <Sql><![CDATA[
+        INSERT INTO ad_session_usage_audit
+        (ad_session_usage_audit_id, ad_client_id, ad_org_id, createdby, 
updatedby, ad_session_id, object_id, ad_module_id, command, classname, 
object_type)
+        VALUES (get_uuid(),'0','0',?,?,?,?,?,?,?,?)
+    ]]></Sql>
+    <Parameter name="userId"/>
+    <Parameter name="userId"/>
+    <Parameter name="sessionId"/>
+    <Parameter name="objectId"/>
+    <Parameter name="moduleId"/>
+    <Parameter name="command"/>
+    <Parameter name="classname"/>
+    <Parameter name="objecttype"/>
+  </SqlMethod>
+  
 </SqlClass>
diff -r ece41d561ffe -r 5cd9e415371e 
src/org/openbravo/erpCommon/security/UsageAudit.java
--- a/src/org/openbravo/erpCommon/security/UsageAudit.java      Mon Feb 07 
13:48:27 2011 +0100
+++ b/src/org/openbravo/erpCommon/security/UsageAudit.java      Mon Feb 07 
14:22:54 2011 +0100
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2011 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -19,9 +19,11 @@
 
 package org.openbravo.erpCommon.security;
 
+import java.sql.Connection;
 import java.sql.SQLException;
 import java.util.Map;
 
+import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
 
@@ -30,7 +32,9 @@
 import org.openbravo.base.secureApp.VariablesSecureApp;
 import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.service.OBDal;
+import org.openbravo.database.ConnectionProvider;
 import org.openbravo.database.SessionInfo;
+import org.openbravo.exception.NoConnectionAvailableException;
 import org.openbravo.model.ad.access.SessionUsageAudit;
 import org.openbravo.model.ad.system.Client;
 import org.openbravo.model.ad.system.SystemInformation;
@@ -112,4 +116,46 @@
       }
     }
   }
+
+  /**
+   * A version of the auditAction not using dal and running in a seperate 
connection/transaction and
+   * which does not commit the currently active dal transaction.
+   */
+  public static void auditActionNoDal(ConnectionProvider conn, 
VariablesSecureApp vars,
+      String javaClassName) {
+    auditActionNoDal(conn, vars.getSessionValue(SESSION_ID_ATTR), 
vars.getCommand(), SessionInfo
+        .getProcessType(), SessionInfo.getModuleId(), 
SessionInfo.getProcessId(), javaClassName);
+  }
+
+  private static void auditActionNoDal(ConnectionProvider conn, String 
sessionId, String action,
+      String objectType, String moduleId, String objectId, String 
javaClassName) {
+
+    final boolean auditAction = sessionId != null && !sessionId.isEmpty() && 
objectType != null
+        && !objectType.isEmpty() && moduleId != null && !moduleId.isEmpty();
+    if (!auditAction) {
+      return;
+    }
+
+    try {
+      final boolean usageAuditEnabled = 
SessionLoginData.isUsageAuditEnabled(conn);
+      if (!usageAuditEnabled) {
+        return;
+      }
+
+      log4j.debug("Auditing sessionId: " + sessionId + " -  action:" + action 
+ " - objectType:"
+          + objectType + " - moduleId:" + moduleId + " - objectId:" + objectId
+          + " - javaClassName:" + javaClassName);
+      Connection con = conn.getTransactionConnection();
+      SessionLoginData.insertUsageAudit(con, conn, SessionInfo.getUserId(), 
sessionId, objectId,
+          moduleId, action, javaClassName, objectType);
+      conn.releaseCommitConnection(con);
+    } catch (ServletException se) {
+      log4j.error("Error inserting usage audit", se);
+    } catch (NoConnectionAvailableException e) {
+      log4j.error("Error getting connection to insert usage audit", e);
+    } catch (SQLException e) {
+      log4j.error("Error inserting usage audit", e);
+    }
+  }
+
 }

------------------------------------------------------------------------------
The modern datacenter depends on network connectivity to access resources
and provide services. The best practices for maximizing a physical server's
connectivity to a physical network are well understood - see how these
rules translate into the virtual world? 
http://p.sf.net/sfu/oracle-sfdevnlfb
_______________________________________________
Openbravo-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openbravo-commits

Reply via email to