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".