Hi!

Thanks for clarifying this Dan.

> Here's my take on this (but I'm not a database expert). We all
> agree that commit option B or C is valuable when the data could
> change underneath the entity. Commit option C is also valuable
> when you don't want your transactions to block at the application
> server level while waiting for the single server instance of an entity
> component.

Agreed.

> For instance, if every order placed uses a number of product
> entities to read data but not write it, you don't want the orders
> queueing up to use the one-and-only instance of product. Instead,
> you want multiple instances of a product. However, it is still
> possible to change the product entity. This is the pattern that
> Rickard is referring to by "read-mostly." If we were modifying it with
> every transaction, it would be better to serialize access to the
> entity state (even with option C). Since we're not, we want to have
> multiple instances to avoid blocking at the application server level.

Yup, correct.

> Now, how do the various entities interact? We "defer concurrency
> control to the database," as mentioned--but not described--in the
> specification. The exact scheme we use to do this can vary. One
> way is to obtain a write lock on the database tables every time we
> use the entity (e.g. select for update). This isn't very good, because
> we will probably still end up blocking other readers during a read-
> only transaction, only at the database level (although this depends
> on the isolation level). Another way is to obtain the data within a
> transaction, which will give you a read lock on the data. When you
> try to write the data within the same transaction, it will attempt to
> promote the read lock to a write lock. This has the disadvantage of
> potentially causing deadlocks.

If one uses Oracle, isn't it the case that the tx is simply rollbacked
instead of deadlocked? That's what I'd guess anyway.

> Finally, you can use optimistic
> concurrency control by reading the data outside of the transaction
> and re-reading it in the transaction before writing it--first validating
> that it has not been changed. You can use a token (e.g. last
> modified number or date) to do this, although a more general
> solution is to check that no values have changed in the "where"
> clause of your second select statement. Note that the exact
> behavior of these locking mechanisms depends on the isolation
> level and the database strategy to implement it.

Yup, right on.

> P.S. In my opinion, commit option C is not "band-aid," but is the
> most generally useful solution. Option A is useful when the cost of
> synchronizing to one entity instance is lower than the cost of
> retrieving the data from the database cache. Option B is a highly
> special-purpose option for circumstances when you have non-
> database resources associated with a particular entity identity, that
> would be costly to reaquire.

Agree. A is for highly cacheable cases, and C is the preferred for clustered
or optimistic case. B is, as you note, useful if ejbActivate/ejbPassivate is
costly.

regards,
  Rickard





Reply via email to