Chris,

This does not really answer my question.  How would you do this in Gemstone for
example?  Would approach 1) work?  If yes explain how Gemstone avoids the
problem I mention.  If not what is the correct way to do it.

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