Author: bpapez
Date: Sun Jun 10 18:33:05 2007
New Revision: 17535

URL: https://svndev.jahia.net/websvn/listing.php?sc=3D1&rev=3D17535&repname=
=3Djahia
Log:
* prevent that the IDGeneratorDAO returns the same ID twice, could happen i=
n cluster if two nodes acquire the next Hi ID at the same time
* switch to newer JBossCache version, due to needed methods for locking a c=
ache entry throughout a cluster even without transaction
* switch to newer versions of some libraries, which are already in use with=
 Jahia 4.2

Modified:
    trunk/core/project.xml
    trunk/core/src/java/org/jahia/hibernate/dao/IDGeneratorDAO.java

Modified: trunk/core/project.xml
URL: https://svndev.jahia.net/websvn/diff.php?path=3D/trunk/core/project.xm=
l&rev=3D17535&repname=3Djahia
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/core/project.xml (original)
+++ trunk/core/project.xml Sun Jun 10 18:33:05 2007
@@ -139,7 +139,7 @@
     <dependency>
       <groupId>commons-dbcp</groupId>
       <artifactId>commons-dbcp</artifactId>
-      <version>1.2.1</version>
+      <version>1.2.2</version>
       <properties>
         <war.bundle>true</war.bundle>
       </properties>
@@ -155,7 +155,7 @@
     <dependency>
       <groupId>commons-digester</groupId>
       <artifactId>commons-digester</artifactId>
-      <version>1.5</version>
+      <version>1.6</version>
       <properties>
          <war.bundle>true</war.bundle>
         <!-- ktlili: clipbuilder
@@ -197,14 +197,22 @@
     <dependency>
       <groupId>commons-jexl</groupId>
       <artifactId>commons-jexl</artifactId>
-      <version>1.0-beta-1</version>
+      <version>1.1</version>
       <properties>
         <war.bundle>true</war.bundle>
       </properties>
     </dependency>
     <dependency>
+      <groupId>commons-lang</groupId>
+      <artifactId>commons-lang</artifactId>
+      <version>2.1</version>
+      <properties>
+        <war.bundle>true</war.bundle>
+      </properties>
+    </dependency>    =

+    <dependency>
       <id>commons-logging</id>
-      <version>1.0.3</version>
+      <version>1.1</version>
       <properties>
          <war.bundle>true</war.bundle>
         <!-- ktlili: clipbuilder
@@ -222,24 +230,16 @@
       </properties>
     </dependency>
     <dependency>
-      <groupId>commons-lang</groupId>
-      <artifactId>commons-lang</artifactId>
-      <version>2.1</version>
-      <properties>
-        <war.bundle>true</war.bundle>
-      </properties>
-    </dependency>
-    <dependency>
       <groupId>commons-pool</groupId>
       <artifactId>commons-pool</artifactId>
-      <version>1.2</version>
+      <version>1.3</version>
       <properties>
         <war.bundle>true</war.bundle>
       </properties>
     </dependency>
       <dependency>
           <id>commons-transaction</id>
-          <version>1.1.1pre1</version>
+          <version>1.2</version>
         <properties>
           <war.bundle>true</war.bundle>
         </properties>
@@ -394,31 +394,19 @@
           <war.bundle>true</war.bundle>
         </properties>
       </dependency>
-
-    <dependency>
-        <groupId>imagej</groupId>
-        <artifactId>imagej</artifactId>
-        <properties>
-          <war.bundle>true</war.bundle>
-        </properties>
-    </dependency>
-
-
-
-
-        <dependency>
-            <!-- slf4j-log4j12 -->
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
-            <version>1.0</version>
-            <url>http://www.slf4j.org/download.html</url>
-            <properties>
-              <war.bundle>true</war.bundle>
-            </properties>
-            <!--
-                SLF4J adapter for log4j.
-            -->
-        </dependency>
+      <dependency>
+          <!-- slf4j-log4j12 -->
+          <groupId>org.slf4j</groupId>
+          <artifactId>slf4j-log4j12</artifactId>
+          <version>1.0</version>
+          <url>http://www.slf4j.org/download.html</url>
+          <properties>
+            <war.bundle>true</war.bundle>
+          </properties>
+          <!--
+              SLF4J adapter for log4j.
+          -->
+      </dependency>
     <dependency>
       <groupId>imagej</groupId>
       <artifactId>imagej</artifactId>
@@ -498,7 +486,7 @@
     <dependency>
       <groupId>jgroups</groupId>
       <artifactId>jgroups-all</artifactId>
-      <version>2.3-beta</version>
+      <version>2.4.1</version>
       <properties>
         <war.bundle>true</war.bundle>
       </properties>
@@ -565,7 +553,7 @@
     <dependency>
       <groupId>log4j</groupId>
       <artifactId>log4j</artifactId>
-      <version>1.2.8</version>
+      <version>1.2.14</version>
       <properties>
          <war.bundle>true</war.bundle>
         <!-- ktlili: clipbuilder
@@ -975,16 +963,8 @@
 =

     <dependency>
       <groupId>xerces</groupId>
-      <artifactId>xmlParserAPIs</artifactId>
-      <version>2.6.2</version>
-      <properties>
-        <war.bundle>false</war.bundle>
-      </properties>
-    </dependency>
-    <dependency>
-      <groupId>xerces</groupId>
       <artifactId>xercesImpl</artifactId>
-      <version>2.6.2</version>
+      <version>2.9</version>
       <properties>
         <war.bundle>true</war.bundle>
       </properties>
@@ -1338,11 +1318,12 @@
         <war.bundle>true</war.bundle>
       </properties>
     </dependency>
-    <!-- XML xpath dep (required for jdk.1.4): xml-apis-2.0.2 -->
+
+    <!-- XML xpath dep (required for jdk.1.4): xml-apis-2.9 -->
     <dependency>
-      <groupId>xml-apis</groupId>
+      <groupId>xerces</groupId>
       <artifactId>xml-apis</artifactId>
-      <version>2.0.2</version>
+      <version>2.9</version>
       <properties>
         <war.bundle>true</war.bundle>
       </properties>
@@ -1480,7 +1461,7 @@
     <dependency>
       <groupId>jboss</groupId>
       <artifactId>jboss-cache</artifactId>
-      <version>1.2.4</version>
+      <version>1.4.1.SP3</version>
       <properties>
         <war.bundle>true</war.bundle>
       </properties>

Modified: trunk/core/src/java/org/jahia/hibernate/dao/IDGeneratorDAO.java
URL: https://svndev.jahia.net/websvn/diff.php?path=3D/trunk/core/src/java/o=
rg/jahia/hibernate/dao/IDGeneratorDAO.java&rev=3D17535&repname=3Djahia
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/core/src/java/org/jahia/hibernate/dao/IDGeneratorDAO.java (origin=
al)
+++ trunk/core/src/java/org/jahia/hibernate/dao/IDGeneratorDAO.java Sun Jun=
 10 18:33:05 2007
@@ -17,8 +17,12 @@
  */package org.jahia.hibernate.dao;
 =

 import org.jahia.exceptions.JahiaException;
+import org.jboss.cache.DataNode;
+import org.jboss.cache.Node;
+import org.jboss.cache.ReplicationException;
 import org.jboss.cache.TreeCache;
 import org.jboss.cache.lock.IsolationLevel;
+import org.jboss.cache.lock.TimeoutException;
 import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
 import org.hibernate.Hibernate;
 import org.hibernate.Session;
@@ -28,21 +32,32 @@
 import java.util.HashMap;
 =

 /**
- * User: Serge Huber
- * Date: 3 nov. 2005
- * Time: 17:41:09
- * Copyright (C) Jahia Inc.
+ * User: Serge Huber Date: 3 nov. 2005 Time: 17:41:09 Copyright (C) Jahia =
Inc.
  */
 public class IDGeneratorDAO extends HibernateDaoSupport {
 =

+    int lockAcquisitionRetryCount;
+
+    long lockAcquisitionTimeout;
+
+    private final static String CACHE_ENTRY_KEY =3D "entryKey";
+
     TreeCache cache;
+
     Map dbSequences;
+
     Map simpleSequences;
+
     String clusterName;
+
     String clusterProperties;
+
     long maxLo =3D 100;
+
     Map lowCounters =3D new HashMap();
+
     Map highCounters =3D new HashMap();
+
     boolean clusterActivated =3D false;
 =

     public synchronized Long getNextLong(String sequenceName) throws Excep=
tion {
@@ -60,29 +75,75 @@
         }
         long highCounter =3D highCounterLong.longValue();
         if (lowCounter >=3D maxLo) {
-            Long newValue =3D (Long) cache.get("/idgenerators", sequenceNa=
me);
-            if (newValue !=3D null) {
-                newValue =3D new Long(newValue.longValue() + maxLo);
+            Long newValue =3D null;
+            int retryCounter =3D lockAcquisitionRetryCount;
+            boolean success =3D false;
+
+            do {
+                Node node =3D null;
+                Long oldValue =3D null;
+                boolean acquired =3D false;
                 try {
-                    cache.put("/idgenerators", sequenceName, newValue);
-                } catch (org.jboss.cache.ReplicationException re) {
-                    logger.warn("Error while replicating last used high va=
lue " + newValue + ", cluster nodes may have crashed or unreacheable" , re);
+                    node =3D cache.get("/idgenerators/" + sequenceName);
+                    if (node.acquire(Thread.currentThread(), cache
+                            .getLockAcquisitionTimeout(),
+                            DataNode.LOCK_TYPE_WRITE)) {
+                        acquired =3D true;
+                        oldValue =3D (Long) cache.get("/idgenerators/"
+                                + sequenceName, CACHE_ENTRY_KEY);
+                        if (oldValue !=3D null) {
+                            newValue =3D new Long(((Long) oldValue).longVa=
lue()
+                                    + maxLo);
+                            oldValue =3D (Long) cache.put("/idgenerators/"
+                                    + sequenceName, CACHE_ENTRY_KEY, newVa=
lue);
+                            if (!newValue.equals(oldValue)) {
+                                lowCounter =3D 0;
+                                highCounter =3D newValue.longValue();
+                                highCounters.put(sequenceName, new Long(
+                                        highCounter));
+
+                                success =3D true;
+                            }
+                        }
+                    }
+                } catch (TimeoutException rep) {
+                    logger.error("Timeout while updating last used high va=
lue "
+                            + newValue, rep);
+                } catch (ReplicationException rep) {
+                    logger.error("Error while replicating last used high v=
alue "
+                            + newValue
+                            + ", cluster nodes may have crashed or unreach=
eable",
+                            rep);
+                } finally {
+                    if (acquired)
+                        node.release(Thread.currentThread());
                 }
-                lowCounter =3D 0;
-                highCounter =3D newValue.longValue();
-                highCounters.put(sequenceName, new Long(highCounter));
+                retryCounter--;
+            } while (retryCounter >=3D 0 && !success);
+
+            if (retryCounter =3D=3D 0) {
+                throw new JahiaException(
+                        "ID incrementor service does not work",
+                        "Acquire idgenerators cache timed out",
+                        JahiaException.CACHE_ERROR,
+                        JahiaException.CRITICAL_SEVERITY);
             }
+
             lowCounters.put(sequenceName, new Long(lowCounter));
-            logger.debug("Returning new ID=3D" + newValue + " for sequence=
 " + sequenceName);
+            logger.debug("Returning new ID=3D" + newValue + " for sequence=
 "
+                    + sequenceName);
             return newValue;
         } else {
             lowCounters.put(sequenceName, new Long(lowCounter));
-            logger.debug("Returning new ID=3D" + new Long(highCounter + lo=
wCounter) + " for sequence " + sequenceName);
+            logger.debug("Returning new ID=3D"
+                    + new Long(highCounter + lowCounter) + " for sequence "
+                    + sequenceName);
             return new Long(highCounter + lowCounter);
         }
     }
 =

-    public synchronized Integer getNextInteger(String sequenceName) throws=
 Exception {
+    public synchronized Integer getNextInteger(String sequenceName)
+            throws Exception {
         Long result =3D getNextLong(sequenceName);
         if (result =3D=3D null) {
             return null;
@@ -106,50 +167,68 @@
 =

         // ok cache is alive, we must now initialize all the generators wi=
th the
         // appropriate default values.
-        Session session =3D getSession();
-        Iterator dbSequencesIter =3D dbSequences.entrySet().iterator();
-        while (dbSequencesIter.hasNext()) {
-            Map.Entry curEntry =3D (Map.Entry) dbSequencesIter.next();
-            String sequenceName =3D (String) curEntry.getKey();
-            String fqnID =3D (String) curEntry.getValue();
-
-            int separatorPos =3D fqnID.indexOf(".");
-            String tableName =3D fqnID.substring(0, separatorPos);
-            String columnName =3D fqnID.substring(separatorPos+1);
-
-            long initialHighValue;
-            long initialLowValue;
-
-            Long curClusterHighValue =3D (Long) cache.get("/idgenerators",=
 sequenceName);
-            if (curClusterHighValue =3D=3D null) {
-                // not found in cluster cache, let's initialize.
-                // @todo add code to perform SELECT MAX() query on database
-                Long maxValue =3D (Long) session.createSQLQuery("SELECT MA=
X("+columnName+") as maxValue FROM " + tableName).addScalar("maxValue", Hib=
ernate.LONG).uniqueResult();
-                initialHighValue =3D 0;
-                initialLowValue =3D 0;
-                if (maxValue =3D=3D null) {
-                    maxValue =3D new Long(0);
+        Session session =3D null;
+        try {
+            session =3D getSession();
+
+            Iterator dbSequencesIter =3D dbSequences.entrySet().iterator();
+            while (dbSequencesIter.hasNext()) {
+                Map.Entry curEntry =3D (Map.Entry) dbSequencesIter.next();
+                String sequenceName =3D (String) curEntry.getKey();
+                String fqnID =3D (String) curEntry.getValue();
+
+                int separatorPos =3D fqnID.indexOf(".");
+                String tableName =3D fqnID.substring(0, separatorPos);
+                String columnName =3D fqnID.substring(separatorPos + 1);
+
+                long initialHighValue;
+                long initialLowValue;
+
+                Long curClusterHighValue =3D (Long) cache.get("/idgenerato=
rs/"
+                        + sequenceName, CACHE_ENTRY_KEY);
+                if (curClusterHighValue =3D=3D null) {
+                    // not found in cluster cache, let's initialize.
+                    // @todo add code to perform SELECT MAX() query on dat=
abase
+                    Long maxValue =3D (Long) session.createSQLQuery(
+                            "SELECT MAX(" + columnName + ") as maxValue FR=
OM "
+                                    + tableName).addScalar("maxValue",
+                            Hibernate.LONG).uniqueResult();
+                    initialHighValue =3D 0;
+                    initialLowValue =3D 0;
+                    if (maxValue =3D=3D null) {
+                        maxValue =3D new Long(0);
+                    } else {
+                        initialHighValue =3D ((maxValue.longValue() / maxL=
o))
+                                * maxLo;
+                        initialLowValue =3D maxValue.longValue() % maxLo;
+                        lowCounters
+                                .put(sequenceName, new Long(initialLowValu=
e));
+                    }
+                    highCounters.put(sequenceName, new Long(initialHighVal=
ue));
+                    logger.debug("Sequence " + sequenceName
+                            + " initial values : low=3D" + initialLowValue
+                            + " high=3D" + initialHighValue);
+                    try {
+                        cache.put("/idgenerators/" + sequenceName,
+                                CACHE_ENTRY_KEY, new Long(initialHighValue=
));
+                    } catch (org.jboss.cache.ReplicationException re) {
+                        logger
+                                .warn(
+                                        "Error while replicating last used=
 high value "
+                                                + initialHighValue
+                                                + ", cluster nodes may hav=
e crashed or unreacheable",
+                                        re);
+                    }
                 } else {
-                    initialHighValue =3D ((maxValue.longValue() / maxLo)) =
* maxLo;
-                    initialLowValue =3D maxValue.longValue() % maxLo;
+                    initialLowValue =3D maxLo; // force high increment on =
first retrieval.
+                    highCounters.put(sequenceName, curClusterHighValue);
                     lowCounters.put(sequenceName, new Long(initialLowValue=
));
                 }
-                highCounters.put(sequenceName, new Long(initialHighValue));
-                logger.debug("Sequence "+sequenceName+" initial values : l=
ow=3D" + initialLowValue +
-                              " high=3D" + initialHighValue );
-                try {
-                    cache.put("/idgenerators", sequenceName, new Long(init=
ialHighValue));
-                } catch (org.jboss.cache.ReplicationException re) {
-                    logger.warn("Error while replicating last used high va=
lue " + initialHighValue + ", cluster nodes may have crashed or unreacheabl=
e" , re);
-                }
-            } else {
-                initialLowValue =3D maxLo; // force high increment on firs=
t retrieval.
-                highCounters.put(sequenceName, curClusterHighValue);
-                lowCounters.put(sequenceName, new Long(initialLowValue));
             }
+            session.flush();
+        } finally {
+            releaseSession(session);
         }
-        session.flush();
-        releaseSession(session);
     }
 =

     public void stop() throws JahiaException {
@@ -204,4 +283,20 @@
     public void setClusterActivated(boolean clusterActivated) {
         this.clusterActivated =3D clusterActivated;
     }
+
+    public long getLockAcquisitionTimeout() {
+        return lockAcquisitionTimeout;
+    }
+
+    public void setLockAcquisitionTimeout(long lockAcquisitionTimeout) {
+        this.lockAcquisitionTimeout =3D lockAcquisitionTimeout;
+    }
+
+    public int getLockAcquisitionRetryCount() {
+        return lockAcquisitionRetryCount;
+    }
+
+    public void setLockAcquisitionRetryCount(int lockAcquisitionRetryCount=
) {
+        this.lockAcquisitionRetryCount =3D lockAcquisitionRetryCount;
+    }
 }

_______________________________________________
cvs_list mailing list
[email protected]
http://lists.jahia.org/cgi-bin/mailman/listinfo/cvs_list

Reply via email to