if anybody has read this before I changed answer for question 28 The following is my summing-up of Monson-Haenffel 421ff. I am not very familiar with the specification yet, but it seems readable.
Summing up made my perspective somewhat clearer. But I might be wrong.
A very important point is that the EJB-Container behaves very differently towards system exceptions or application exceptions during transactions.
What are system exceptions, what are application exceptions?
An system exception is any exception that does extend java.lang.RuntimeException or java.rmi.RemotExceptions. EJBException extends Runtime exception.
All the rest are application-exception. Some of the EJB life-cycle and the finders throw application exception (e.g. CreateException, DuplicateKeyException, FinderException, etc.).
(as we all know from basic java:
A method is not required to declare in its throws clause any subclasses of RuntimeException that might be thrown during the execution of the method but not caught.
)
If you define your own exceptions in an ejb method
you should use application exceptions.
Some of the standard exceptions of ejb-lifecycle and finder exceptions are application-exceptions too (for example: CreateException, DuplicatedKeyException, FinderException, ObjectNotFoundException, etc..
In what do they behave differently?
A system exception is handled automatically by the container:
- the transaction is rolled back
- the exception is locked)
- the transaction is rolledBack
- the ejb instance is discarded.
The last one invalidates the clients reference to the EJB. Subsequent method calls on the home or remote interface result in a NoSuchObjectException (subclass of RemoteException)
A application exception does n.o.t result in a transaction rollback. Although one ressource won't commit (an application exception is thrown) the transaction manager will commit the transaction (heuristic decision). This may lead to inconsistent data.
Whats the reason for that different behaviour?
The idea is that the client-(code) can recover through correcting the application exception. If this is not possible, you can use the method setRollbackOnly() of the javax.transaction.UserTransaction interface. A dereferenced, garbage collected ejb instance sometimes is to strong as an effect.
And if I can't correct the error?
That's what setRollbackOnly() in the UserTransaction interface is for: You can veto transactions. Transactions marked with setRollbackOnly() can't be commited.
25)
a)
spans multiple method calls. must be stateful.
NO
b)
if it is a system-exception the ejb-object would be dereferenced. If application exception commit would be possible (without call to setRollbackOnly()
NO
c)
this won't result in an illegal state exception, but a TransactionRolledBackException
NO
d)
The Session bean method that starts the transaction was never called.
YES
28)
see explanation above.
a)
no
b)
yes
c)
(no)
d)
(yes)
29)
a)
YES. If so, one would have to commit the transaction and start a new one before call on businessmethod2.
b)
YES. Same as a)
c)
YES. Same as a)
d)
NO. This will be written when transaction is commited.
Don't believe blindly what I say.
Correct me if I am wrong.
More questions. More answers.
Axel
[ May 27, 2002: Message edited by: Axel Janssen ]
[ May 27, 2002: Message edited by: Axel Janssen ]