dan benanav wrote:
>
> This is a long babbling letter so if you want to hear my conclusions
> and not my babbling I will state it first.
>
> 1. Design your entity beans to only contain update methods. Rely on
> pessimistic concurrency. In fact the ability to achieve serialization
> of calls using pessimistic concurrency is a major programming
> advantage and a major reason for using entity beans. Otherwise I would
> just use a stateless session bean.
I still believe entity beans are damn good for read methods as well,
especially if you can select an optimistic model. Plus, you can get
caching.
Moreso, for update you might want to use session beans with UPDATE,
rather than entity beans with SELECT followed by UPDATE.
> 2. For methods that are read only use a stateless session bean.
>
> If that entices you read on to see how I am led to this conclusion.
>
> Note in the following pessimistic concurrency refers to using only one
> bean per entity object. That is, if Entity object A and B are
> identical (same primary key) then all business calls are delegated to
> the same bean instance.
I truely support that model, but I'm afraid not all EJB developers will
be aware of that, since the spec doesn't spell that out for them.
In essence, your entity bean is a stateless bean, i.e. method calls can
be directed to any instance, the EJB server needs to figure out how many
instances to support (one for all, one per transaction, etc).
> I am beginning to conclude that when it comes to methods that update
> the bean, pessimistic concurrency is most often what is required and
> that it will not affect efficiency. The problems discussed below
> regarding incorrect results go away if pessimistic concurrency can be
> enforced. So the spec should allow that to be specified in the
> deployment descriptor.
+1 on that.
> For methods that update the beans, optimistic concurrency might be
> useful if the following 2 conditions are met.
>
> 1. Multiple clients will often make update calls to the same entity
> object.
> 2. The 2 calls are independent of one another. Meaning for example
> that they depend on and change different parts of the bean.
2. doesn't compute for me.
> So if we want multiple readers single writers we have a problem. The
> solution to this might be to use a stateless session bean for reads
> and the entity bean only for methods that update. This seems OK to me
> except for one thing. The benefits of a cached ejb bean are lost
> now. (Am I correct here? Is there a way to enforce caching of the
> entity bean? Meaning that when findByPrimarykey the container looks
> for a bean that already exists with the same primary key. Also it
> doesn't call ejbLoad on that bean?)
No way to enforce it, but an EJB server should allow you to configure
that.
In my opinion you should have a flag that tells whether the bean is:
1. Pessimitic -- all references should see one instance and only one
instance
2. Optimistic (cached) -- each transaction can see it's own instance,
the bean can be cached
3. Read only -- each transaction can see it's own instance, the bean is
never stored
What you should be able to do is take the same bean, deploy it three
times with different concurrency levels and different names. Something
like:
lookup( "java:comp/env/ejb/my-bean-PL" );
will return a bean from a pessimistic locking container,
lookup( "java:comp/env/ejb/my-bean-RO" );
will return the same bean type (different instance) from a read only
container, etc.
> 1. For most cases using entity beans with pessimistic concurrency is
> what you want. Furthermore you actually want to rely on pessimistic
> concurrency in terms of correctness of your program.
+1 Optimistic locking might scale better, but might violate your
transaction integrity, so unless you have time to worry about that,
start with pessimistic and build from that.
> 2. For methods that do not update the database try to write the bean
> so that ejbStore only makes updates if the fields have changed. (What
> is the best way to do that?) I looked at WLS examples and it seems
> ugly and dangerous to me.
CMP will compare the instance against a known image from the cache and
determine whether it changed or not. In addition, a method like
isModified (I think WLS supports it) can tell the container whether
ejbStore should occur or not.
BMP can do so at ejbStore.
> This whole discussion brings us back to another conclusion. "This
> should be easy and obvious, but it's not"! And that is what I don't
> like about ejb. It is a love hate relationship I have with ejb.
> Can't live with it and can't live without it. :-)
I agree with you on the subject line 100%.
arkin
>
>
> dan
>
>
>
>
>
>
> Chris Raber wrote:
>
> > Assaf,
> >
> > Some fine points. Comments:
> >
> > > -----Original Message-----
> > > From: Assaf Arkin [SMTP:[EMAIL PROTECTED]]
> > > Sent: Wednesday, February 09, 2000 4:23 PM
> > > To: [EMAIL PROTECTED]
> > > Subject: Re: This should be easy an obvious, but it's not.
> > >
> > > Chris, one clarification (I'm now dicussing the same issue with
> > RMH on a
> > > separate thread).
> > >
> > > Assume we're always talking about the same identity, because
> > that's
> > > where the problem is. You have two transactions T1 and T2 finding
> > and
> > > then calling methods on instances of that identity.
> > >
> > > I agree that T1 and T2 should not attempt to access the same
> > instance,
> > > that would just kill performance.
> > >
> > Check.
> >
> > > My question is, if T1 attempts to find the identity twice, will it
> >
> > > always get the same identity A, or will it get two identities in
> > the
> > > same transaction?
> > >
> > It should find the same physical instance A as long as it is in the
> > same
> > address space. If T1 is distributed over more than one server,
> > another
> > identical A could get instantiated, using yet another resource... In
> >
> > GemStone/J we have a "co-location" policy so that once we cross over
> > into
> > the server, activation of one component by another forces a load in
> > the same
> > server process.
> >
> > I can't think through the detail on short notice, but perhaps if you
> > had a
> > long transaction started way out at the client, and the client
> > looked up
> > components in multiple app server instances, you could get a
> > distributed
> > transaction where the same identity was accessed with two/more
> > different XA
> > resources. Seems far fetched, and I would never architect that way,
> > but you
> > never know what people will dream up!
> >
> > > Also, what happens if T1 is using a remote reference Ra, T2 is
> > using a
> > > remote reference Rb, and now T1 is using Rb as well?
> > >
> > Luckily the remote reference and the instances that gets invoked can
> > be
> > separate in EJBs. Remember it is the XA resource Behind the beans
> > that get
> > registered with the transaction manager, so as long as the EJB
> > server
> > properly propagates transaction resources and keeps its resource
> > book-keeping straight, everything should be ok.
> >
> > > arkin
> > >
> > >
> > > Chris Raber wrote:
> > > >
> > > > Dan,
> > > >
> > > > I think the bottom line is that the EJB server has to provide
> > > transaction
> > > > isolation to the simultaneous operations on our beans. In
> > GemStone/J we
> > > do
> > > > this by having separate instances of the bean per transaction,
> > and the
> > > > datasource handles the concurrency issues. This works as long as
> > we have
> > > > over lapping transactions.
> > > >
> > > > If you pull data out of the beans, copy it to the client, update
> > the
> > > data,
> > > > and write it back to the bean in a separate transaction than the
> >
> > > original
> > > > read, then you must use optimistic concurrency control (i.e.
> > "dirty
> > > > detection"...).
> > > >
> > > > Other servers will handle this by synchronizing access to a
> > single bean
> > > > instance at the Java level. This will perform very poorly for
> > update
> > > intense
> > > > applications.
> > > >
> > > > Regards,
> > > >
> > > > -Chris.
> > > >
> > > > > -----Original Message-----
> > > > > From: dan benanav [SMTP:[EMAIL PROTECTED]]
> > > > > Sent: Wednesday, February 09, 2000 7:50 AM
> > > > > To: [EMAIL PROTECTED]
> > > > > Subject: This should be easy an obvious, but it's not.
> > > > >
> > > > > I have a question about how to implement something using EJB.
> > I am
> > > sure
> > > > > that this problem is very common and that it has come up in
> > > discussions
> > > > > in various forms on this list, but I don't think the right
> > approach
> > > has
> > > > > been clarified. This is surprising since the spec should be
> > able to
> > > > > handle such a situation rather easily. It appears to me that
> > many
> > > > > people have a misunderstanding about EJB that leads to an
> > incorrect
> > > way
> > > > > to solve this problem. Including in that misunderstanding is
> > the Sun
> > > > > BluePrints guide. In the following I will assume we are
> > talking EJB
> > > 1.1
> > > > > spec and I am interested in a solution that conforms to that
> > spec.
> > > > >
> > > > > Problem: Suppose you have an Account class that is the remote
> >
> > > interface
> > > > > to an Account bean. AccountBean is the entity bean
> > implementation
> > > > > class. You want to write a method increment(int x) that adds
> > x to the
> > > > > balance on the account represented by the Account instance.
> > There are
> > > 2
> > > > > approaches that come to mind about how to do this. The first
> > is the
> > > > > most obvious but I believe there are problems with it.
> > > > >
> > > > > 1) public void increment(int x) {balance += x;};
> > > > >
> > > > > 2) public void increment(int x) { //use jdbc to increment the
> > balance
> > > in
> > > > > the db using sql like "updateaccount_table set balance =
> > balance + ?
> > > > > where account_key = ?". The first question mark is set to x
> > and the
> > > > > second question mark is set to the primary key of the bean.}
> > > > >
> > > > > Why isn't 1) good? Containers are free to use multiple bean
> > instances
> > > > > to handle concurrent calls to an entity object as long as
> > those calls
> > > > > are occurring under a different transaction. This means that
> > you can
> > > > > have bean instance A and bean instance B both handling calls
> > to
> > > > > increment x, where both A and B represent the same entity
> > object (same
> > > > > primary key). Some containers my choose not to do this,
> > however there
> > > > > is no guarantee that the container provider won't change their
> >
> > > approach
> > > > > in the future. Furthermore if you rely on the container not
> > doing
> > > that
> > > > > your code will not work on any EJB server. This would make it
> >
> > > difficult
> > > > > for EJB bean providers (like the Theory Center) for providing
> > server
> > > or
> > > > > container independent beans. So if you agree now that your
> > code
> > > should
> > > > > work if the Container provider uses multiple bean instances
> > then I
> > > think
> > > > > there is a problem. Suppose that in two separate threads
> > calls are
> > > > > made to an entity object. One thread calls increment(1) and
> > the other
> > > > > increment(2). These calls occur concurrently. Assume also
> > that the
> > > > > initial balance before the calls is 3. After the call the new
> > balance
> > > > > should be 6. Here is what can occur:
> > > > >
> > > > > T1:Container calls ejbLoad on Bean A: Balance gets set to 3.
> > > > > T2:Container calls ejbLoad on Bean B: Balance still is 3.
> > (This
> > > > > happens in a separate thread and separate transaction
> > context).
> > > > > T3:Container calls increment(1) on Bean A: Balance gets set to
> > 4 in
> > > Bean
> > > > > A.
> > > > > T4:Container calls increment(2) on Bean B: Balance gets set to
> > 5 in
> > > Bean
> > > > > B.
> > > > > T5:Container calls ejbStore on Bean A: balance in database is
> > updates
> > > to
> > > > > 4.
> > > > > T6:Container calls ejbStore on Bean B: what happens??
> > > > >
> > > > > What happens may depend on what the Transaction isolation
> > level is and
> > > > > perhaps on the underlying database. If you use Oracle and the
> > default
> > > > > transaction isolation level (read committed) then the balance
> > gets set
> > > > > to 5 in the database. (The wrong answer!). If you use
> > serializable
> > > > > transaction isolation level then an exception is thrown and
> > the client
> > > > > will have to react appropriately to the exception. So it
> > would appear
> > > > > that the only way 1) could possibly work (in some sense) is
> > to use
> > > > > transaction level serializable. So 1) with transaction
> > serializable
> > > is
> > > > > an approach but it is incompletely specified since we haven't
> > said how
> > > > > the client should handle this. I imagine there are ways to
> > handle it.
> > > > > (Catch the exception and try again for example). Furthermore
> > I have
> > > > > been told by WLS not to use transaction serializable due to a
> > bug in
> > > > > Oracle so 1) does not currently work for Oracle. Even if
> > this would
> > > > > work it seems like it would be better to just force the
> > container or
> > > to
> > > > > specify in the deployment descriptor that calls to increment
> > should be
> > > > > serialized. Currently there is no way to do that in the spec.
> >
> > > > >
> > > > > The second solution would work however there are also problems
> > with
> > > it.
> > > > > You need to be careful to make sure that when ejbStore is
> > called the
> > > > > correct value is stored in the database. For example, you
> > cannot just
> > > > > increment the value in the db. You would also need to set
> > balance in
> > > the
> > > > > bean appropriately.
> > > > >
> > > > > So the question is, how should one implement this? Surely we
> > should
> > > be
> > > > > able to reach a consensus on this rather simple question?
> > > > >
> > > > > dan
> > > > >
> > > > >
> > >
> > ==========================================================================
> >
> > > > > =
> > > > > To unsubscribe, send email to [EMAIL PROTECTED] and
> > include in the
> > > > > body
> > > > > of the message "signoff EJB-INTEREST". For general help, send
> > email
> > > to
> > > > > [EMAIL PROTECTED] and include in the body of the message
> > "help".
> > > >
> > > >
> > >
> > ==========================================================================
> >
> > > =
> > > > To unsubscribe, send email to [EMAIL PROTECTED] and include
> > in the
> > > body
> > > > of the message "signoff EJB-INTEREST". For general help, send
> > email to
> > > > [EMAIL PROTECTED] and include in the body of the message
> > "help".
> > >
> > > --
> > >
> > ----------------------------------------------------------------------
> >
> > > Assaf Arkin
> > www.exoffice.com
> > > CTO, Exoffice Technologies, Inc.
> > www.exolab.org
> > >
> > >
> > ==========================================================================
> >
> > > =
> > > To unsubscribe, send email to [EMAIL PROTECTED] and include in
> > the
> > > body
> > > of the message "signoff EJB-INTEREST". For general help, send
> > email to
> > > [EMAIL PROTECTED] and include in the body of the message
> > "help".
> >
> > =======
> > ===================================================================
> > To unsubscribe, send email to [EMAIL PROTECTED] and include in
> > the body
> > of the message "signoff EJB-INTEREST". For general help, send email
> > to
> > [EMAIL PROTECTED] and include in the body of the message "help".
--
----------------------------------------------------------------------
Assaf Arkin www.exoffice.com
CTO, Exoffice Technologies, Inc. www.exolab.org
===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff EJB-INTEREST". For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".