Hi

I have 2 Jboss3.2.5 applications servers working in a cluster.
I'm using for primary key generation The pattern "sequence blocks" taken from 
the book ejb design patterns.
However when i have something like 5 threads that are trying to create new 
entities then i get DuplikateKeyException on the primary key.  (with only 1 
jboss server not in a cluster everything is fine).
I was wondering if anybody could help me pin out the problem, following is my 
code:

I estimated it might be an Isolation level problem, however i have updated the 
isolation level to be serializable in that way in mysql ds  and the problem 
still happend...

    <user-name>root</user-name>
  |     <password></password>
  |     <TransactionIsolation>TRANSACTION_SERIALIZABLE</TransactionIsolation>
  | 


Sequence entity bean


  | package messaging_as.domain.util;
  | 
  | import javax.ejb.*;
  | 
  | import messaging_as.util.jmx.ConfigContainer;
  | 
  | abstract public class SequenceBean implements EntityBean {
  |   EntityContext entityContext;
  |   public java.lang.String ejbCreate(java.lang.String name) throws 
CreateException {
  |     setName(name);
  |     return null;
  |   }
  |   public void ejbPostCreate(java.lang.String name) throws CreateException {
  |     
setSIndex(ConfigContainer.getJMXPropertiesFacade().getSequenceSessionBeanStartIndex());
  |   }
  | 
  |   public void ejbRemove() throws RemoveException {
  |   }
  | 
  |   public abstract void setName(java.lang.String name);
  |   public abstract void setSIndex(int sIndex);
  |   public abstract java.lang.String getName();
  |   public abstract int getSIndex();
  |   public void ejbLoad() {
  |   }
  | 
  |   public void ejbStore() {
  |   }
  | 
  |   public void ejbActivate() {
  |   }
  | 
  |   public void ejbPassivate() {
  |   }
  | 
  |   public void unsetEntityContext() {
  |     this.entityContext = null;
  |   }
  |   public void setEntityContext(EntityContext entityContext) {
  |     this.entityContext = entityContext;
  |   }
  |   public int getValueAfterIncrementingBy(int blockSize) {
  |     this.setSIndex(this.getSIndex()+ blockSize);
  |     return this.getSIndex();
  |   }
  | }
  | 

sequence session bean


  | package messaging_as.domain.util;
  | 
  | import java.sql.Connection;
  | import java.sql.ResultSet;
  | import java.sql.SQLException;
  | import java.sql.Statement;
  | 
  | import javax.ejb.CreateException;
  | import javax.ejb.FinderException;
  | import javax.ejb.SessionBean;
  | import javax.ejb.SessionContext;
  | import javax.naming.Context;
  | import javax.naming.NamingException;
  | 
  | import messaging_as.domain.AlbumElementHome;
  | import messaging_as.domain.AlbumElementShareHome;
  | import messaging_as.domain.UserHome;
  | import messaging_as.service.exceptions.InternalException;
  | import messaging_as.util.jmx.JMXPropertiesFacade;
  | import messaging_as.util.sql.MASConnectionManager;
  | 
  | import org.apache.log4j.Category;
  | 
  | public class SequenceSessionBean implements SessionBean {
  |   SessionContext sessionContext;
  |   private Category _log;
  |   private class Entry {
  |     Sequence sequence;
  |     int last;
  |   };
  | 
  |   private java.util.HashMap _entries = new java.util.HashMap();
  |   private int _blockSize;
  |   private int _retryCount;
  |   private SequenceHome _sequenceHome;
  | 
  |   public void ejbCreate() throws CreateException {
  |     _log = Category.getInstance(getClass());
  |   }
  | 
  |   public void ejbRemove() {
  | 
  |   }
  |   public void ejbActivate() {
  | 
  |   }
  |   public void ejbPassivate() {
  | 
  |   }
  | 
  |   public void setSessionContext(SessionContext sessionContext) {
  |     this.sessionContext = sessionContext;
  |     Context namingContext = null;
  |     try {
  |       namingContext = new javax.naming.InitialContext();
  |       _blockSize = 
JMXPropertiesFacade.getInstance().getSequenceSessionBeanBlockSize();
  |       _retryCount = 
JMXPropertiesFacade.getInstance().getSequenceSessionBeanRetryCount();
  | 
  |       _sequenceHome = (SequenceHome) 
namingContext.lookup("SequenceLocalHome");
  |     }
  |     catch (NamingException e) {
  |       _log.error(e.getMessage(), e);
  |     }
  |   }
  |   
  |   public void synch() throws InternalException {
  |     Connection connection = null;
  |     ResultSet resultSet = null;
  |     Statement statement = null;
  |     int maxObjectID = 0, maxUID = 0, maxShareID = 0;
  |     try {
  |       connection = MASConnectionManager.getInstance().createConnection();
  |       
  |       String sql = "select max(" + AlbumElementHome.FIELD_NAME_OBJECT_ID + 
") maxObjectID from " + AlbumElementHome.TABLE_NAME;
  |       statement = connection.createStatement();
  |       _log.debug("SQL : " + sql);
  |       statement.execute(sql);
  |       resultSet = statement.getResultSet();
  |       if (resultSet.next()) {
  |         maxObjectID = resultSet.getInt("maxObjectID");
  |         _log.debug(String.valueOf(maxObjectID));
  |       }
  |       resultSet.close();
  |       statement.close();
  |       ((Sequence) 
_sequenceHome.findByPrimaryKey(AlbumElementHome.JNDI_NAME)).setSIndex(maxObjectID
 + 1);
  |       
  |       sql = "select max(" + UserHome.FIELD_UID + ") maxUID from " + 
UserHome.TABLE_NAME;
  |       statement = connection.createStatement();
  |       _log.debug("SQL : " + sql);
  |       statement.execute(sql);
  |       resultSet = statement.getResultSet();
  |       if (resultSet.next()) {
  |         maxUID = resultSet.getInt("maxUID");
  |         _log.debug(String.valueOf(maxUID));
  |       }
  |       resultSet.close();
  |       statement.close();
  |       ((Sequence) 
_sequenceHome.findByPrimaryKey(UserHome.JNDI_NAME)).setSIndex(maxUID + 1);
  |       
  |       sql = "select max(" + AlbumElementShareHome.FIELD_SHARE_ID + ") 
maxShareID from " + AlbumElementShareHome.TABLE_NAME;
  |       statement = connection.createStatement();
  |       _log.debug("SQL : " + sql);
  |       statement.execute(sql);
  |       resultSet = statement.getResultSet();
  |       if (resultSet.next()) {
  |         maxShareID = resultSet.getInt("maxShareID");
  |         _log.debug(String.valueOf(maxShareID));
  |       }
  |       resultSet.close();
  |       statement.close();
  |       ((Sequence) 
_sequenceHome.findByPrimaryKey(AlbumElementShareHome.JNDI_NAME)).setSIndex(maxShareID
 + 1);
  |       
  |     } catch (SQLException e1) {
  |       _log.error(e1.getMessage(), e1);
  |     } catch (FinderException e) {
  |       throw new InternalException(e);
  |     } finally {
  |         try {
  |           if (connection != null && !connection.isClosed()) 
connection.close();
  |         } catch (SQLException e) {
  |           _log.error(e.getMessage(), e);
  |         }
  |     }
  |     
  |   }
  | 
  |   public int getNextSequenceNumber(String name) {
  |     try
  |     {
  |         Entry entry = (Entry) _entries.get(name);
  | 
  |         if (entry == null)
  |         {
  |             // add an entry to the sequence table
  |             entry = new Entry();
  |             try
  |             {
  |                 entry.sequence = _sequenceHome.findByPrimaryKey(name);
  |             }
  |             catch (javax.ejb.FinderException e)
  |             {
  |                 _log.info("can't find sequence: " + name + " trying to 
create it");
  |                 // if we couldn't find it, then create it...
  |                 entry.sequence = _sequenceHome.create(name);
  |                 _log.info("sequence: " + name + " created");
  |             }
  |             _entries.put(name, entry);
  |         }
  |         if (entry.last % _blockSize == 0)
  |         {
  |             for (int retry = 0; true; retry++)
  |             {
  |                 try
  |                 {
  |                     entry.last = 
entry.sequence.getValueAfterIncrementingBy(_blockSize);
  |                     break;
  |                 }
  |                 catch (javax.ejb.TransactionRolledbackLocalException e)
  |                 {
  |                     if (retry < _retryCount)
  |                     {
  |                         // we hit a concurrency exception, so try again...
  |                         _log.info("RETRYING");
  |                         continue;
  |                     }
  |                     else
  |                     {
  |                               // we tried too many times, so fail...
  |                         throw new javax.ejb.EJBException(e);
  |                     }
  |                 }
  |             }
  |         }
  | 
  |         return entry.last++;
  |     }
  |     catch (javax.ejb.CreateException e)
  |     {
  |         throw new javax.ejb.EJBException(e);
  |     }
  | }
  | 
  | 
  | }
  | 

from ejb-jar.xml


  |         <container-transaction>
  |             <method>
  |                 <description />
  |                 <ejb-name>SequenceSession</ejb-name>
  |                 <method-name>getNextSequenceNumber</method-name>
  |                 <method-params>
  |                     <method-param>java.lang.String</method-param>
  |                 </method-params>
  |             </method>
  |             <trans-attribute>RequiresNew</trans-attribute>
  |         </container-transaction>
  | 

jboss.xml


  |    <container-configurations>
  |      <container-configuration>
  |         <container-name>Standard CMP 2.x EntityBean with cache 
invalidation</container-name>
  |             <commit-option>A</commit-option>
  |             <cache-invalidation>True</cache-invalidation>
  |      </container-configuration>
  |    </container-configurations>
  | .
  | .
  | .
  |       <entity>
  |         <ejb-name>Sequence</ejb-name>
  |         <local-jndi-name>SequenceLocalHome</local-jndi-name>
  |         <!-- no cache for this entity bean -->
  |       </entity>
  | 

anybody can help with what the problem might be?
did i update the isolation level correctly?

View the original post : 
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=3881060#3881060

Reply to the post : 
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=3881060


-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games.  How far can you shotput
a projector? How fast can you ride your desk chair down the office luge track?
If you want to score the big prize, get to know the little guy.  
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
_______________________________________________
JBoss-user mailing list
JBoss-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jboss-user

Reply via email to