To simplify the problem let's assume we are using BMP.
If you obtain a lock in ejbLoad it will apply to every method invocation that is
transaction required. So all
method invocations will block others. Seems to me that does not provide a practical
granularity.
I think your answer seems to validate my remarks. The simple requirements are not
easily met in EJB!
Assaf Arkin wrote:
> [EMAIL PROTECTED] wrote:
> >
> > I understand that ejbLoad will occur but Oracle will doesn't lock the row
> > when reading. Also are you saying that the container obtains a read lock
> > in an ejbLoad? How does it do that?
>
> Container only obtains a lock in CMP, in BMP you have to do it youself.
>
> In CMP that would happen through SELECT ... FOR UPDATE (Oracle) or
> SELECT ... HOLDLOCK or SERIALIZABLE (Sybase). You can do the same in BMP
> if you need to synchronize access.
>
> Alternatively, you might want to open up a cursor in BMP with ejbLoad
> and use it for ejbStore. (Not that I would recommend that with the
> current state of EJB containers and JDBC drivers :-) )
>
> The guidelines for BMP would be:
>
> * If only one entity can access the data at a given time then:
>
> ejbLoad must do a FOR UPDATE (or anything equivalent)
>
> The server guarantees to do ejbLoad at least once in the transaction
> and ejbStore when the transaction commits (not before)
>
> * Or, if the server is smarter, you might declare the entity bean as
> exclusive access and the EJB server will serialize method calls across
> transactions
>
> * If you want two entity beans to access the data at a given time, then:
>
> Your business methods must do UPDATE, not count on the information
> you loaded in ejbLoad
>
> Or, your ejbStore must do the UPDATE smartly
>
> * One possibility is to have:
>
> int getBalance() but not setBalance()
>
> have a field called increment which is not persistence, so
> setIncrement() getIncremenet()
>
> in ejbStore you would do an UPDATE balance += incremenet;
>
> arkin
>
> >
> > dan
> >
> >
> > Assaf Arkin
> > <arkin@exoffic To: dan benanav
><[EMAIL PROTECTED]>
> > e.com> cc: [EMAIL PROTECTED],
>[EMAIL PROTECTED]
> > Sent by: Subject: Re: [EJB-INT] This should
>be easy an obvious, but it's
> > [EMAIL PROTECTED] not.
> > office.com
> >
> >
> > 02/09/00 03:15
> > PM
> >
> >
> >
> > > I dont think that is correct. Oracle provides for row level
> > > locking. There is no update in ejbLoad so no locking occurs.
> > > Locking only occurs when you update a row. See the following from the
> > > Oracle site:
> >
> > You do need ejbLoad to occur. If it doesn't then someone else might
> > update the database from outside the server, and your problem will not
> > be just two beans racing to get the update first. So by definition, you
> > need to synchronize first, which means an ejbLoad, which means you get a
> > read lock on the row, which means serializable access.
> >
> > Excatly how you get that done is up to the EJB container.
> >
> > >
> > > Row-Level Locking
> >
> > <snip>
> > I know, I wrote code like that for the CMP engine.
> > </snip>
> >
> > arkin
> >
> > > >
> > > >
> > > > But, if you opened a connection from a session bean with read
> > > > committed,
> > > > then ran the entity bean from it, you're still in read committed, so
> > > > the
> > > > serializable doesn't work for you.
> > > >
> > > > This is where the EJB server should allow you to mark the entity
> > > > bean as
> > > > exclusive access and maintain a lock, blocking B until A finishes
> > > > the
> > > > transaction. I'm working on code that does just that right now, and
> > > > it's
> > > > not that hard.
> > > >
> > > > Once again, lock contention.
> > > >
> > > > If you're looking for performance (and scalability and everything
> > > > else)
> > > > you should consider either:
> > > >
> > > > 1. Doing no 2) (in UPDATE from the entity bean), or
> > > >
> > > > 2. Using a stateless session bean (my favorite)
> > > >
> > > > You must always assume the EJB entity bean mantra of
> > > > load-modify-commit,
> > > > which either gets you into trouble if you don't pay attention to
> > > > locking, or slows down your application if you do too much locking.
> > > >
> > > > arkin
> > > >
> > > > dan benanav wrote:
> > > > >
> > > > > 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.
> > > > >
> > > > >
> > > > > 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".
> > > >
> > > > --
> > > > --
> > > > -------------------------------------------------------------------
> > > > Assaf Arkin
> > > > www.exoffice.com
> > > > CTO, Exoffice Technologies, Inc.
> > > > www.exolab.org
> >
> > --
> > ----------------------------------------------------------------------
> > Assaf Arkin www.exoffice.com
> > CTO, Exoffice Technologies, Inc. www.exolab.org
>
> --
> ----------------------------------------------------------------------
> Assaf Arkin www.exoffice.com
> CTO, Exoffice Technologies, Inc. www.exolab.org
===========================================================================
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".