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
[email protected]
https://lists.sourceforge.net/lists/listinfo/jboss-user