Hi,
Rickard �berg wrote:
> marc fleury wrote:
> > It doesn't address the client holding of the version he is looking at (the
> > client gets a "copy" of the values and when he comes back he needs a version
> > number)
>
> The client gets a snapshot of the data, INCLUDING a version number.
> Client then edits that data. The the client sends back the data. If the
> version on the server is the same as in the snapshot the client is
> sending back, then all is well. If there is a mismatch then some other
> client made an update, and the client gets an exception.
I believe this pattern to be widely used. For example Nordija has
a publicly available web interface (at www.nordija.com or
www.nordija.dk, I don't remember) to some bean generator that
generates beans that do this.
Personally I don't like it as it adds extra state (version number)
that the client needs to have.
Another pattern that does not add extra state, but creates a little
more traffic on updates can be exemplified by:
We have a Person entity bean and an Address value object. The
Person bean has normal bean pattern for accessing and modifying
the address property:
Address getAddress();
void setAddress(Address adr);
The problem is the same as above: If we want a user to edit the
address and update it in the bean we risk that another user
updates it too while the user is editing. The simple fix is to
have a single ACID transaction spanning the whole get-edit-update
process, but that is undesirable as nobody knows how long it may
take the user to edit (ie. lunch break during editing). To get
around this a logical business transaction is done so that get
and update are ACID transactions that are part of the business
transaction, but the edit step is outside any ACID transactions
but inside the business transaction. Problem with this is that
another user can update the address during the first user's
editing.
This could be fixed by adding a data version number as proposed,
but there is another way:
Instead a new method
void setNewAddress(Address oldAdr, Address newAdr)
throws ConcurrentUpdateException;
is added and used for the update step of the business transaction.
The oldAdr argument is the address that the user read on start of
the business transaction, and newAdr the the result of user
editing. If the current contents of address in the Person bean
is not equal to oldAdr or newAdr, an exception is thrown.
Besides the fact that no extra state is needed with this approach,
this has the added advantage that concurrent edits do not cause
an exception if:
a) Another field is changed.
b) The same field is changed, and then changed back to the old
value before the original business transaction does the
update.
c) If the same field was changed to the new value. In this case
the update is just a no-op.
In any case, I do not think that support for business
transaction should belong to the EJB container or server.
IMHO this is better done by bean programmers and generators.
Why? Business transaction may be _very_ complex. The "user
edits some data" business transaction is just a very simple
example.
A more complex example could be found in an order entry system,
where "create a new order" is a business transaction with
the following requirements:
- Other users should not see the new order until the business
transaction is committed.
- Stock inventory should be pre-allocated as the user enters
each new order line, so that the business transaction commit
will not fail with an out-of-stock exception.
Even Peter Herzum (who advocates the notion of business
transactions) acknowledges that even with extensive framework
support for business transactions, only about 80% of all
business transactions can be done within the framework.
Best Regards,
Ole Husgaard.
--
--------------------------------------------------------------
To subscribe: [EMAIL PROTECTED]
To unsubscribe: [EMAIL PROTECTED]
Problems?: [EMAIL PROTECTED]