I think Jonathon summarized the concurrency issues faced by some of us
developers who are writing applications that really care about concurrency.
The proposed solution of using a "verified update" works very well in single
table situations, and it also works when a updateable view can be
constructed between more than one table.
I like this type of solution specifically because it *doesn't* require
database serialization. Serialization on the database, even in highly
sensitive concurrent-aware applications, should often be avoided. My opinion
of course, but besides the performance reason, and the fact that not all
databases support it, there are real-life business logic reasons for
avoiding it. There are many times in my current application where a
serializable isolation level on the database would prevent me from
validating amounts. I have hierarchies of objects, and when the amounts
change in a particular object, I have to make sure that it doesn't blow the
cap of an ancestor object. This is very efficiently achieved by using
read-uncommitted isolation.
Another "real-life" problem with serialized isolation is the record locking
level. Few databases support row-level locking (anecdotal, maybe this has
changed), and those that do are often deployed with page-level locking for
performance reasons. With page-level locking, many transactions would be
falsely rejected because they are "too close" too a record that is being
modified.
=========================
I find that a larger problem (that Jonathon also discussed) is the updating
of dependent objects. These objects will frequently exist in tables other
than the bean's "primary" table. Some applications will have the requirement
that two users can make concurrent changes to a bean and it's dependent
objects. For example, consider the "restaurant order" bean. It is feasible
that one waiter could change the table associated with the order (a change
to the bean - primary table), while a waitress could simultaneously change
the order items (a dependent object - ancillary table).
Implementing this in a generic manner seems very foreboding. I attempted to
implement a "concurrency grid" that held information that determined which
dependent objects could be modified without concern for concurrency. Imagine
our order bean has two dependent objects DEP_A, and DEP_B. Also imagine that
we grant clients the right to modify DEP_A and DEP_B concurrently. We also
allow the Order Bean and DEP_A to be modified concurrently. We forbid the
concurrent modification of any single object (bean or dependent), and
concurrent changes to the Order Bean and DEP_B.
Order DEP_A DEP_B
+-------+-------+-------+
Order | A43BD | | 9043B |
+-------+-------+-------+
DEP_A | | 65CE9 | |
+-------+-------+-------+
DEP_B | F930A | | 07F10 |
+-------+-------+-------+
By using the concurrency grid, the EJB can examine concurrent collisions by
looking up an intersection in the grid. If there is a UID (timestamp,
generated id, etc.) present at the intersection, it's value could be checked
against the previous "intersection UID". If it is the same, the update
proceeds. The update writes a new intersection UID into the concurrency
grid. The other concurrent transaction would end up with a different
intersection UID and could be rejected.
There were some implementation difficulties with this approach that I
couldn't easily solve. One major problem I faced was the concurrency grid
acted somewhat like a semaphore. The concurrency grid in many ways became
another dependent object of the bean. I was writing it to a database and
this was causing me some grief because I had to use serializable isolation
on it. I had put the concurrency grids for all of my objects in a single
table, and page-level locking was causing much headaches. For the current
project, we don't allow concurrent updating of the bean.
FWIW, the grid above can be reduced in size since it is symmetrical along
the diagonal.
=========================
The whole issue of relying on the container to provide concurrency control
has been a farce. WebLogic is doing its users a disservice by "implying"
that they need not worry about concurrency because the container will
serialize access to identical entity beans. I had read stuff like this in
the past. Now that they have a clustered container solution, maybe they are
backing away from this approach.
The only true place to implement concurrency is at the database or at a
layer between all of the EJB containers and the database. You can only
implement concurrency in *one* location. No matter how scalable we attempt
to make our systems, there is always a place where all of our traffic
funnels down to a single point. This place is the only place to implement a
concurrency algorithm. For 95% of us that care about it, it is the database.
=========================
Typically, I find that most people simply don't care about concurrency. If
their app has low contention, they feel that the risk of corruption is not
worth the extra work. I'm just glad they are not working on *my* project
that will be managing billions of dollars per year down to the penny. ;-)
jim
===========================================================================
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".