Posted by mister__m
on December 29, 2003 at 6:56 PM PST
Do you work with J2EE? How many times have you written code that called setRollbackOnly()? Never called it? I am afraid that is why some of your transactions aren't working properly...
Not having the burden of managing transactions by yourself - a.k.a Container Managed Transactions, CMT for short - is a compelling reason for using EJBs. Obviously, EJB is not the only technology that gives you that, but that's a entirely different discussion. Back to the point, the fact you don't have to call any transaction management method neither in
java.sql.Connection nor in any class contained in
javax.transaction makes a lot of people happy - especially those who already experienced the painful job of calling these manually. Although CMT is good and works - ok, in decent containers, let me be sincere here -, it is not magic and you have certain rules to obey so the container can do its job.
The most obvious thing - at least it should be - you should do is to specify which transaction attribute applies to each method in each EJB you wrote. There are a bunch of ways of doing it in the deployment descriptor, from specifying different attributes to each overloaded version of a method to using the same for all of them, and some containers have decent default values for when you don't declare anything, but I'm not going to cover this here. Today's point is more subtle than that and is something I've seen a considerable number of developers - including some good ones - not doing: calling
, superclass of
is the interface that contains this method. The J2EE 1.4 javadoc description for this method is:
Mark the current transaction for rollback. The transaction will become permanently marked for rollback. A transaction marked for rollback can never commit. Only enterprise beans with container-managed transactions are allowed to use this method.
Note that only EJBs that use CMT - most of them - are allowed to use this method. But when are they required to? When it must be called? The answer is relatively simple, but astonishing for some people (from now on, everything here refers to CMT EJBs). Let's start to answer these questions by taking a look at section 126.96.36.199 of the recently published EJB 2.1 spec:
Typically, an enterprise bean marks a transaction for rollback to protect data integrity before throwing an application exception, because application exceptions do not automatically cause the container to rollback the transaction.
I highlighted the bold part and I wish it was already printed in bold in the pdf, actually. A lot of people read this section and simply ignore this important sentence. An application exception does not cause the container to rollback a transaction. It is a simple, but ignored fact. But what is an application exception? Section 18.1.1 defines it:
An application exception is an exception defined in the throws clause of a method of an enterprise bean