From: Timo K. <ko...@jy...> - 2003-04-17 18:11:57
|
Hi. I am rookie with JBOSS. But could it be possible that you are using "Instance Per Transaction Policy" with your CMP beans ? Read the <container-configurations> part in $JBOSS_HOME/server/default/conf/standardjboss.xml and check what your application's jboss.xml says about container-configuration. -- Timo On Thursday 17 April 2003 12:33, Brian McSweeney wrote: > Hi Jos, > > thanks for the reply. I really want to get this solved. The first step in > understanding why it is happening is to clear up what transactions > should be doing. > > > A transaction does not perform locking in order to guarantee mutually > > exclusive access to a row. > > Is this definately true? I quote from the JBoss Admin developer guide, > p181: > > "A transaction lock ensures that only one transaction at a time has > access to a give Entity Bean. This ensures the ACID properties > of transactions at the application server level. Since, by default, > there is only one active instance of any given Entity Bean at one time, > JBoss must protect this instance from dirty reads and dirty writes. > So, the default Entity Bean locking behavior will lock an Entity Bean > within a transaction until it completes. This means that if any method > at all is invoked on an Entity Bean within a transaction, > no other transaction can have access to this bean until the > holding trans-action commits or is rolled back. " > > again this is repeated on page 182: > > "The default locking policy of JBoss is to lock an Entity bean when an > invocation occurs in the context of a transaction until the transaction > completes." > > Now I know that this might be obvious to some people, but can > somebody please give me a definative explanation of what > transactions actually lock using JBoss!!!????? > > This is fundamental to what JBoss is used for and surely someone > can tell me. > thanks, > Brian > > > ----- Original Message ----- > From: "Jos Visser" <jo...@os...> > To: <jbo...@li...> > Sent: Thursday, April 17, 2003 9:29 AM > Subject: Re: [JBoss-user] Fundamental error > > > Hi, > > > > As far as I can see, this has nothing to do with transactions, but more > > with the fact that lots of people misunderstand transactions. > > > > The implementation of the Sequence Pattern that lots of people use is > > fundamentally broken, because it does not withstand two threads calling > > nextValue() each in their own transaction from returning the same > > (supposedly unique, but in fact not) value. > > > > See also the interesting thread on this at: > > > > http://www.theserverside.com/patterns/thread.jsp?thread_id=220 > > > > A transaction does not perform locking in order to guarantee mutually > > exclusive access to a row. > > > > ++Jos.nl > > > > And thus it came to pass that Brian McSweeney wrote: > > (on Mon, Apr 07, 2003 at 05:26:25PM +0100 to be exact) > > > > > Hi all, > > > > > > we have a fundamental problem with primary key generation with JBoss > > using > > > > the > > > xpetstore UIDGenerator component. This component has two classes. A > > session > > > > facade UIDGeneratorEJB which has a method getUniqueId, which calls a > > > nextValue > > > method on an entity bean ( CounterEJB ). This is an implementation of > > Floyd > > > > Marinescu's > > > Sequence pattern. > > > > > > The UIDGeneratorEJB is marked transaction required. However a simple > > test > > > > shows that > > > several threads are able to similtaniously call nextValue and get back > > the > > > > same integer. > > > Something is surely critically wrong with our implementation or with > > JBoss. > > > > This scenario happens on JBoss 3.x with MySql. > > > > > > The two xpetstore files are below with a simple test class. > > > > > > Any help at all would be very much appreciated. > > > > > > Brian > > > > > > file://------------- > > > > > > package xpetstore.util.uidgen.ejb; > > > > > > import javax.ejb.EJBException; > > > import javax.ejb.FinderException; > > > import javax.ejb.SessionBean; > > > > > > import xpetstore.util.uidgen.interfaces.CounterLocal; > > > import xpetstore.util.uidgen.interfaces.CounterLocalHome; > > > import xpetstore.util.uidgen.util.CounterUtil; > > > > > > > > > /** > > > * @author <a href="mailto:tch...@us...">Herve > > > Tchepannou</a> > > > * > > > * @ejb.bean > > > * name="UIDGenerator" > > > * type="Stateless" > > > * local-jndi-name="local/xpetstore.util.uidgen.UIDGenerator" > > > * view-type="local" > > > * @ejb.transaction > > > * type="Required" > > > * @ejb.util > > > * generate="physical" > > > */ > > > public abstract class UIDGeneratorEJB > > > implements SessionBean > > > { > > > file://~ > > > Methods > > > ---------------------------------------------------------------- > > > > > > file://================================= > > > // Business Methods > > > file://================================= > > > > > > /** > > > * @ejb.interface-method > > > */ > > > public int getUniqueId( String idPrefix ) > > > { > > > return getCounter( idPrefix ).nextValue( ); > > > } > > > > > > file://================================= > > > // Misc Method > > > file://================================= > > > private CounterLocal getCounter( String name ) > > > { > > > try > > > { > > > CounterLocal counter = null; > > > CounterLocalHome home = CounterUtil.getLocalHome( ); > > > > > > try > > > { > > > counter = home.findByPrimaryKey( name ); > > > } > > > catch ( FinderException fe ) > > > { > > > counter = home.create( name ); > > > } > > > > > > return counter; > > > } > > > catch ( Exception ce ) > > > { > > > throw new EJBException( "Could not create counter " + name > > > + > > ". > > > > Error: " + ce.getMessage( ) ); > > > } > > > } > > > } > > > > > > > > > > > > package xpetstore.util.uidgen.ejb; > > > > > > import javax.ejb.CreateException; > > > import javax.ejb.EntityBean; > > > > > > > > > /** > > > * @author <a href="mailto:tch...@us...">Herve > > > Tchepannou</a> > > > * > > > * @ejb.bean > > > * name="Counter" > > > * type="CMP" > > > * view-type="local" > > > * local-jndi-name="local/xpetstore.util.uidgen.Counter" > > > * primkey-field="name" > > > * schema="Counter" > > > * cmp-version="${ejb.cmp.version}" > > > * @ejb.transaction > > > * type="Required" > > > * @ejb.util > > > * generate="physical" > > > * @ejb.persistence > > > * table-name="T_COUNTER" > > > * > > > * @jboss.persistence > > > * create-table="${jboss.create.table}" > > > * remove-table="${jboss.remove.table}" > > > */ > > > public abstract class CounterEJB > > > implements EntityBean > > > { > > > file://~ > > > Methods > > > ---------------------------------------------------------------- > > > > > > file://================================= > > > // Business methods > > > file://================================= > > > > > > /** > > > * @ejb.interface-method > > > */ > > > public int nextValue( ) > > > { > > > int value = getValue( ) + 1; > > > setValue( value ); > > > > > > return value; > > > } > > > > > > file://======================================== > > > // CMP fields > > > file://======================================== > > > > > > /** > > > * @ejb.pk-field > > > * @ejb.persistence > > > * column-name="cnt_name" > > > * jdbc-type="VARCHAR" > > > * sql-type="varchar(50)" > > > * @ejb.interface-method > > > * @ejb.transaction > > > * type="NotSupported" > > > */ > > > public abstract String getName( ); > > > > > > public abstract void setName( String name ); > > > > > > /** > > > * @ejb.persistence > > > * column-name="cnt_value" > > > */ > > > public abstract int getValue( ); > > > > > > public abstract void setValue( int value ); > > > > > > file://======================================== > > > // EJB callbacks > > > file://======================================== > > > > > > /** > > > * @ejb.create-method > > > */ > > > public String ejbCreate( String name ) > > > throws CreateException > > > { > > > setName( name ); > > > setValue( 0 ); > > > > > > return null; > > > } > > > > > > public void ejbPostCreate( String name ) > > > throws CreateException {} > > > } > > > > > > > > > > > > package xpetstore.util.uidgen.test; > > > > > > import javax.ejb.CreateException; > > > > > > import javax.naming.NamingException; > > > > > > import junit.framework.*; > > > > > > import xpetstore.util.uidgen.util.UIDGeneratorUtil; > > > > > > > > > public class UIDGenTest > > > extends TestCase > > > { > > > file://~ Static > > > fields/initializers --------------------------------------------- > > > > > > private static String COUNTER = "Test"; > > > > > > file://~ > > > Constructors > > > ----------------------------------------------------------- > > > > > > public UIDGenTest( String name ) > > > { > > > super( name ); > > > } > > > > > > file://~ > > > Methods > > > ---------------------------------------------------------------- > > > > > > public void testCounter( ) > > > throws Exception > > > { > > > System.out.println( "Testing counter creation" ); > > > > > > for ( int i = 0; i < 10; i++ ) > > > { > > > Thread t = new CounterThread( "Thread " + i ); > > > t.start( ); > > > } > > > } > > > > > > private void count( String name ) > > > throws CreateException > > > { > > > int uid; > > > try > > > { > > > uid = > > > neratorUtil.getLocalHome( ).create( ).getUniqueId( COUNTER ); > > > } > > > catch ( NamingException n ) > > > { > > > throw new CreateException( "Unable to generate the UId. > > Error=" > > > > + n.toString( ) ); > > > } > > > > > > System.out.println( "The counter created is: " + uid + ", > > created > > > > by: " + name ); > > > } > > > > > > file://~ Inner > > > Classes ---------------------------------------------------------- > > > > > > private class CounterThread > > > extends Thread > > > { > > > file://~ Instance > > > fields ---------------------------------------------------- > > > > > > private String name = ""; > > > > > > file://~ > > > Constructors ------------------------------------------------------- > > > > > > public CounterThread( String str ) > > > { > > > super( str ); > > > name = str; > > > } > > > > > > file://~ > > > Methods ------------------------------------------------------------ > > > > > > public void run( ) > > > { > > > while ( true ) > > > { > > > try > > > { > > > count( name ); > > > } > > > catch ( CreateException ce ) > > > { > > > System.err.println( "Couldn't create" ); > > > } > > > } > > > } > > > } > > > } > > > > > > > > > > > > ------------------------------------------------------- > > > This SF.net email is sponsored by: ValueWeb: > > > Dedicated Hosting for just $79/mo with 500 GB of bandwidth! > > > No other company gives more support or power for your dedicated server > > > http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/ > > > _______________________________________________ > > > JBoss-user mailing list > > > JBo...@li... > > > https://lists.sourceforge.net/lists/listinfo/jboss-user > > > > -- > > We should often be ashamed of our finest actions if the world > > understood our motives. > > "Francois de La Rochefoucauld" > > > > > > > > ------------------------------------------------------- > > This sf.net email is sponsored by:ThinkGeek > > Welcome to geek heaven. > > http://thinkgeek.com/sf > > _______________________________________________ > > JBoss-user mailing list > > JBo...@li... > > https://lists.sourceforge.net/lists/listinfo/jboss-user > > ------------------------------------------------------- > This sf.net email is sponsored by:ThinkGeek > Welcome to geek heaven. > http://thinkgeek.com/sf > _______________________________________________ > JBoss-user mailing list > JBo...@li... > https://lists.sourceforge.net/lists/listinfo/jboss-user |