[thelist] Re: Confused on EJB Container Managed Transactions

VOLKAN ÖZÇELİK volkan.ozcelik at gmail.com
Thu Jul 28 01:49:32 CDT 2005


Replying to my own post:

EJB transactions work somewhat different than plain JDBC transactions:

When an EJB transaction begins (by entering a business method when
using CMT, or by explicitly starting via JTA when using BMT) the
apropriate entity bean's ejbLoad() method is called. Which basically
sends SQL selects to the DB to get the most recent state of the bean.
And when the business method ends the bean's ejbStore() method is
called which basically does SQL Updates or Inserts to the DB.

If anything goes wrong in between, a system exception is thrown and
the EJB transaction is rolled back.

If anything goes wrong during ejbLoad() or ejbStore() and if a System
Exception (EJBException) is thrown in the meantime, the transaction is
rolled back.

A CMP example for it will be like:

at ejbStore:
try {
   //do some jdbc
}
catch(SQLException e) {
   throw new EJBException("Transaction rolled back due to " + e.getMessage());
}
finally {
   //cleanup any resources being used.
}

The container talks to Data Persistence Media (filesystem, database,
any other medium that can store / retrieve data persistently) only
during ejbLoad and ejbStore. No real jdbc transaction happens, and no
data is stored/retrieved from the db (or the persistence medium used)
in between these methods.

Moreover, it is up to the container to call ejbLoad() and ejbStore().
It can call these methods whenever it likes, it can call them multiple
times. The mere thing the spec guarantees is that ejbLoad() will be
called at the beginning of an EJB Transaction (CMT or BMT) and
ejbStore() will be called at the and of the EJB Transaction.

When ejb container rolls back its transaction, and if any db changes
that have been made during the transaction (via one or more the Entity
Beans' ejbLoad() methods that engage in the transaction), the spec
guarantees that the data will be set to its original state just before
entering the transaction. This can be easily achieved because Entity
Beans know their state data before the beginning of the transaction
and re-update any data changed.

In addition, the spec says that the data will be persisted to its
original state even if the database shuts down (to do this apropriate
SQL updates will be called as soon as the DB wakes up).

( I had rtfm a lot to come up to this point :) )

To sum up, the ACIDity of EJB transactions are accomplished with EJB
container's (say system) methods.

With the light of the above introduction we can conclude that it is
impossible to roll back direct SQL statements using EJB transactions
but not using any entity beans to store the persistence and 
relations. This can be handled by explicitly calling JDBC
transactions. However EJB transaction are more bullet-proof than JDBC
transactions.

I had known these all before, how I came to this simple point of
confusion is yet another story.

Just wanted to share, and hope it may help to resolve some one else's
questions in their mind.
(
Or better, generate questions in their minds so that they research
more and more and more. There is no better way to learn things than
reading everthing on an issue, reading thoughts of the guru's,
assimilating them and boiling dozens of thoughts on your own pot.
Curiosity is a really good motivation.
)

Cheers,
Volkan.


On 7/26/05, VOLKAN ÖZÇELİK <volkan.ozcelik at gmail.com> wrote:
> Hi evolters!
> 
> I am sure this is the only list to solve my confusion.
> 
> My question is on J2EE.
> And it may be a damn simple one, sorry for that.
> 
> * * *
> 
> Let us say I have a method doBusinessLogic in my stateless session bean as
> 
> void doBusinessLogic() {
>   try {
>        con = ... make jndi lookup and obtain a connection
> 
>        1. con.execute("INSERT INTO SOME TABLE");
>        2. con.execute("EXEC SOME SP");
>        3. con.execute("DELETE SOMETHING FROM SOME OTHER TABLE");
>        4. con.execute("SOME OTHER DB STUFF");
>   }
>   catch(ZillionsOfExceptions ze) {
>        ze.printStacTrace();
>   }
>   finally() {release resources}
> }
> 
> (I know that I have to use prepared statements etc, the above is just
> a simplified semi-pseudocode.)
> 
> Now to the question:
> 
> Given that the method uses container managed transaction, if the
> statements (1 up to 4) were ejb setter methods that use CMP for
> persisting into DB, instead of hard coded SQL calls;
> 
> like
> 
> 1. myBean.setSomehting(123);
> 2. myBean.setSomeOtherThing("lorem dolorem");
> 3. etc
> 
> then when in the middle of the transaction (say at statement 2) an
> exception is thrown; myBean.setSomething should be rolled back
> (
> since the container generates the apropriate insert SQL behind the
> scenes and knows the value before insert (i.e. it remembers it's
> former state), it will not be a big deal for it to set the related
> table(s) back to their original state.
> )
> 
> * * *
> 
> However, in our case we are using hardcoded SQL statements.
> So if, take for example an SQLException is thrown at statement 4
> ("SOME OTHER DB STUFF");
> 
> will the ejb-container ever be able to roll back the entire transaction?
> 
> Or is it "what has been always going on" and I am just unaware of it?
> 
> imho, it is quite impossible for the container to roll back hardcoded
> SQL executes. Else life would be really really easy:
> There would be no duplicate key exceptions, no foreign key problems,
> no duped data: peace at home, peace all over the world :)
> 
> (
> one more thing for the non-J2EE:
> note that I do not use any "begin tran" or "commit tran" in the method.
> So there is no actual database transaction,
> only an ejb container managed transaction exists.
> )
> 
> Hope I was clear on expressing my problem. And hope, someone has a
> clear-cut answer for it. Else I will be having a series sleepless
> nights with this question pondering in my mind all the time.
> 
> Thanks a lot in advance.
> 
> Cheers,
> Volkan.
>


More information about the thelist mailing list