Hi all,

i wanted to let you join some of the misunderstandings i had concerning
transactions and their safety/isolation levels, since i am not a learned
database programmer but have come to databases/ejb accidently (ok, i had to
earn money ;-).

I compared the access to a data entity (in the ejb server) from different
clients always with the in-memory access of an object in shared memory from
different threads (and this analogy is somewhat misleading, as you will
see).
In memory, you have the possibility to lock the object prior to each access
(or to let it be locked by the language/system you use), even if it is only
read access. That means, once read an object, nobody else (no other thread)
will be allowed to even see this object - and the thread will be suspended
until the object is released by the other thread. This system is safe if
every thread completes its computation and releases its locks (and on
abnormal termination a release of all locks could be made by the system).

My misunderstanding now was, that i always searched for a transaction type
in EJB, which provides similar safety and did not understand well the
slightly difference between read locks and the isolation level "repeatable
read" (and that i did not read accurate all availiable literature but relied
on my intentions).
But "repeatable read" does only guarantee, that during a transaction of a
client a read on the same entity will lead to the same result unless this
client itself changes the entity, regardless off parallel working other
clients which could change this entity. But another client will not be
halted if it wants to read this entity. If then both clients want to modify
the same entity after they have read it both (and therefore it cannot be
changed directly due to the "repeatable read"), we get a wunderful deadlock.

Let us take an entity X and the clients A and B, in paranthesis my
assumptions of what happens in the server.

A reads X                       <- allowed (make a copy?)
                B reads X       <- allowed (make a copy?)
A writes X                      <- allowed (change A's copy?)? Or already
forbidden (if there are no copys)?
                B writes X  <- forbidden in any case, result would be
undeterministic

This situation leads to a deadlock exception, which has to be handled
appropriate by the clients. In short words: If programming a client i must
bear in mind that concurrent accesses may lead to exceptions (and rollbacks
of transactions).

What's more with databases (my entity beans use BMP): If the database has
locked a data entity, another "client" (bean) that wants to access this
entity will not be halted until the lock is released but will get an
exception (and there is no - standard - way to decide, wether the thrown
SQLException was caused by a lock/deadlock or by other failures, since the
result codes vary for each database). So, writing beans with BMP that will
be accessed for writing concurrently (i mean the same entity, not the type)
by different clients is really a big deal. BTW, it would be interesting,
what fallback mechanisms for these cases are provided by orion's CMP - i
never used it myself ;-)

Just a little excurs for those who are interested (reading it now, i have
the impression that i really had "tomatos on my eyes", as we say in Germany,
but these misunderstandings have been really expensive in terms of time and
money for my company).

Best regards to all,

Jens

PS: Are there any databases in the world, which provide a real safe lock
mechanism for concurrent read/write access?  I mean, a real lock beginning
with the read? And an automatic wait for a request if some resources are
locked? Would be hot on the market, i think...

PPS: Many of these problems could be handled with the wood-hammer-method
(another germanism, i fear) of repeating a whole failed transaction
automatically by the server as provided by orion with the "max-tx-retries"
feature - unfortunately it does not seem to work yet...


> -----Urspr�ngliche Nachricht-----
> Von: Jens Stutte [mailto:[EMAIL PROTECTED]]
> Gesendet am: Montag, 26. Juni 2000 15:17
> An: Orion-Interest
> Cc: '[EMAIL PROTECTED]'
> Betreff: AW: DeadlockException
>
> Thanx for the answer.
>
> Of course i can get deadlocks as i work against a database - but this
> deadlock seems to be caused by orion itself prior of
> accessing the database.
> Orion must have some internal locking mechanisms to avoid
> concurrent access
> to entity bean variables, i assume. And the 'resource
> entity's mentioned in
> the exception are orion specific and have nothing to do with
> my database
> (which i update myself via BMP). I'd like to know if orion's
> isolation level
> "repeatable_read" is equivalent to someting like "exclusive
> read" (which
> would avoid any deadlocks if the data gets locked for read
> and write until
> the end of a transaction). Furthermore the setting of
> "max-tx-retries" would
> help repeating a failed exception, but i did not get it work.
>
> Regards,
>
> Jens Stutte
>
> -----Urspr�ngliche Nachricht-----
> Von: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED]]
> Gesendet am: Montag, 26. Juni 2000 14:48
> An: [EMAIL PROTECTED]
> Betreff: RE: DeadlockException
>
> Hi!
>
> The short answare is that it's your fault. You can get deadlocks in
> everyform of applications working against a database. And as
> a result of
> some applications sharing the same database and taking out
> locks in the
> database blocking each other. Deadlocks are a commen problem
> when one are
> developing applications for big shared database. One should
> always handle
> them.
>
> A few tips for programming against a database in general:
>
> Keep locks as little as possible.
> Always use transaction around updates.
>
> For ejb there are som extra rules. Recomended reading for you is:
> http://java.sun.com/j2ee/j2sdkee/techdocs/guides/ejb/html/DevG
> uideTOC.html
>
> I would also recomend you to read about programing 2-tier database
> applications as the same principals apply to programming in a j2ee
> enviorments. You are just adding some design rules as this is a 3-tier
> enviorment.
>
> As a rule of tomb always use a Session bean to access a
> entitybean. Never
> access them directly. Let your buisness logic in the
> sessionbeans take care
> of the transaction logic.
>
> In your case from the stacktrace you have two different
> connections to orion
> that simutaniously are trying to update the same database row
> or rows on the
> same page. (Depending on your databaseserver) As I see from
> the stacktrace
> you are doing an update. Do you remember dataintegrety?
>
> An easy tip is to add a timestamp to table and check against
> it if you are
> doing an update. If it has changed do a rolback and give the
> user an error
> about that the data has changed. If you get a rolback because
>  of a deadlock
> just try to do the opperation again, but remember to have this test.
>
> Regards,
> Torgeir
>
> -----Original Message-----
> From: Jens Stutte [mailto:[EMAIL PROTECTED]]
> Sent: 26. juni 2000 13:37
> To: Orion-Interest
> Cc: '[EMAIL PROTECTED]'
> Subject: DeadlockException
>
>
> Hi,
>
> i'm not sure, if this could be a bug, but often concurrent
> access to my
> beans lead to the following Exception:
>
> com.evermind.server.rmi.OrionRemoteException: Transaction was
> rolled back:
> thread 5 is waiting for resource entity 28417 in Site held by
> thread 6 in
> transaction [Transaction
> 85:0:0:0:0:0:0:0:0:df:0:df:fc:c2:ea:4b] who is
> waiting for resource entity 29185 in Site held by thread 5 in
> transaction
> [Transaction 83:0:0:0:0:0:0:0:0:df:0:df:fc:c2:ea:10]
>         at
> EntityBeanWrapper0.setText(EntityBeanWrapper0.java, Compiled
> Code)
>         at java.lang.reflect.Method.invoke(Native Method)
>         at com.evermind.server.rmi.ba.run(JAX)
>         at com.evermind.server.rmi.a8.gu(JAX, Compiled Code)
>         at com.evermind.server.rmi.a8.run(JAX, Compiled Code)
>         at com.evermind.util.e.run(JAX, Compiled Code)
> at connection to beatnix.net-media.de/10.0.1.13 as admin
>         at com.evermind.server.rmi.a8.invokeMethod(JAX)
>         at com.evermind.server.rmi.a_.invoke(JAX)
>         at __Proxy3.setText(Unknown Source)
>         at
> de.netmedia.ejb.test.clienttest.addWords(clienttest.java:113)
>         at de.netmedia.ejb.test.clienttest.main(clienttest.java:271)
>
>         Nested exception is:
> com.evermind.server.DeadlockException: thread 5 is waiting
> for resource
> entity 28417 in Site held by thread 6 in transaction [Transaction
> 85:0:0:0:0:0:0:0:0:df:0:df:fc:c2:ea:4b] who is waiting for
> resource entity
> 29185 in Site held by thread 5 in transaction [Transaction
> 83:0:0:0:0:0:0:0:0:df:0:df:fc:c2:ea:10]
>         at com.evermind.server.ejb.AbstractEJBObject.startCall(JAX)
>         at
> EntityBeanWrapper4.addEntry(EntityBeanWrapper4.java, Compiled
> Code)
>         at
> de.netmedia.ejb.base.accesshashbean.NMejbAccessHashBean.addEnt
> ry(NMejbAccess
> HashBean.java, Compiled Code)
>         at
> StatelessSessionBeanWrapper16.addEntry(StatelessSessionBeanWra
> pper16.java,
> Compiled Code)
>         at
> de.netmedia.ejb.interfaces.server.NMejbString.addToHash(NMejbS
> tring.java,
> Compiled Code)
>         at
> de.netmedia.ejb.interfaces.server.NMejbValue.set(NMejbValue.java,
> Compiled Code)
>         at
> de.netmedia.ejb.interfaces.server.NMejbString.set(NMejbString.
> java, Compiled
> Code)
>         at
> de.netmedia.ejb.base.basebean.NMejbBaseBean.setValueIntern(NMe
> jbBaseBean.jav
> a, Compiled Code)
>         at
> de.netmedia.ejb.base.basebean.NMejbBaseBean.setValue(NMejbBase
> Bean.java,
> Compiled Code)
>         at
> de.netmedia.ejb.base.binarybean.NMejbBinaryBean.setText(NMejbB
> inaryBean.java
> , Compiled Code)
>         at
> EntityBeanWrapper0.setText(EntityBeanWrapper0.java, Compiled
> Code)
>         at java.lang.reflect.Method.invoke(Native Method)
>         at com.evermind.server.rmi.ba.run(JAX)
>         at com.evermind.server.rmi.a8.gu(JAX, Compiled Code)
>         at com.evermind.server.rmi.a8.run(JAX, Compiled Code)
>         at com.evermind.util.e.run(JAX, Compiled Code)
> at connection to beatnix.net-media.de/10.0.1.13
>         at com.evermind.server.rmi.OrionRemoteException.gy(JAX)
>         at com.evermind.server.rmi.a8.gr(JAX)
>         at com.evermind.server.rmi.a8.run(JAX)
>         at java.lang.Thread.run(Thread.java:484)
>
> Is this a programming issue, that is, my fault? And if so,
> how do i get
> information on what's going wrong? Or (as i hope ;-) should
> orion assure
> that there will be no deadlocks of this kind? Note that i set
> the isolation
> level to "repeatable_read".
>
> Regards,
>
> Jens Stutte
>
> PS: My last few postings did not recieve any answer, if my
> questions are
> stupid or annoying or if i should register (and pay) for
> further support,
> please let me know.
>
> ____________________________________________
> [EMAIL PROTECTED], http://www.netmedia.de
>
> NetMedia GmbH
> Neugrabenweg 5-7
> 66123 Saarbruecken
> Germany
>
> fon: +49 (0) 681 - 3 79 88 - 0
> fax: +49 (0) 681 -�3 79 88 - 99
>
>

Reply via email to