Chris Raber wrote:

> Dan,
>
> Sorry for the delay. Busy busy...
>
> You said:
>
> > Chris,
> >
> > This does not really answer my question.  How would you do this in
> > Gemstone for
> > example?  Would approach 1) work?
> >
> I am having a bit of a problem following your analysis below. Separate bean
> instances for the same bean identity would each have their own transactional
> view of the bean state. Assume the counter state is 3 at the beginning of
> transaction, each increment will bump the counter to 4. Which ever
> transaction commits first (and therefor calls ejbStore) will update the
> counter in the database to 4. The other transaction will fail due to
> transaction conflict (in the transaction serializable case). In the read
> committed case, I am not sure whether a lock is implied or not.
>

No lock is implied and that is the problem.  The database is incorrectly
updated.

>
> In the case of GemStone/J PCA, we detect collisions between overlapping
> transacations at the object level, so the second transaction to commit would
> fail. In RDBMS it will depend on the vendors treatment of isolation levels.
>

I don't want the transaction to fail.  I want it to block at the object level
and I would like to do that without having to program that.  So what I want is
pessimistic concurrency and I want to be assured that pessimistic concurrency is
used not matter what ejb server I am using.

>
> We are leaning toward recommending optimistic concurrency and dirty checking
> in all cases to make concurrency behavior consistent across all isolation
> models. This also handles the case where state is pulled from the bean and
> passed over to the client outside of transaction. Since long transactions
> are undesirable, it is likely that optimistic concurrency controls and dirty
> checking are called for anyway.

So if you use optimistic concurrency you would be forced to use transaction
serializable and have the client handle exceptions.  That may be OK (except that
I hear Oracle has a major bug with TRANSACTION SERIALIZABLE).  Also I think that
I would prefer in many cases just to have the container serialize the calls so
that clients don't have to worry about it.

>
>
> So it is not so much an issue of GemStone/J vs anything else, but a matter
> of best design practice for transactional systems. This is old wisdom.

I guess where we disagree is that I think that it is often desirable to force
serialization of the calls and you think that is not necessary. If I don't do
that I will have to, in a loop, continually try transactions whenever I get the
exception generated and to use TRANSACTION SERIALIZABLE, or I will have to do
dirty checking and then try again.

>
>
> > If yes explain how Gemstone avoids the
> > problem I mention.  If not what is the correct way to do it.
> >
> I hope I did that...
>
> Regards,
>
> -Chris.
>
> > 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".

Reply via email to