• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Beginners question on EJB & transactions

 
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am trying to write my first EJB using container managed transactions. I have defined the EJB and added a container transaction type of Required to it.

The EJB method adds records to 2 different database tables and when I force an error to occur with the 2nd insert it doesn't rollback the 1st.

Is there something else that I need to do? I assumed that if the method on the EJB exited with an exception then it would automatically rollback. Is this not right?

Thanks in advance,
Adrian
 
Ranch Hand
Posts: 1683
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Rollback will occur if a system exception is thrown from your bean code to the container. This system exception must be RuntimeException (or a subclass thereof). Check that your code is not throwing a checked exception, eg SQLException. If so, wrap it in EJBException and throw this exception.
 
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There are two kind of exceptions specified in the EJB Specification.

1. Application exceptions: These are meant to be handled by the application(developer). So, when you catch the exception you may call setRollbackOnly() to rollback the transaction otherwise the transaction will be committed.

2. System exceptions: when a system exception is thrown than the transaction is rolled back.
Typically,this happens because the exception or error is unexpected, or the exception is expected but the EJB Provider does not know how to recover from it. Examples of such exceptions and errors are: failure to obtain a database connection, JNDI exceptions, unexpected RemoteException from invocation of other enterprise beans, unexpected RuntimeException, JVM errors, and so on.
 
Adrian Bates
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the replies guys.

So in my test case where I am forcing it to throw an application exception, DuplicateKeyException, I can catch this and throw an EJBException instead and this will cause a rollback? Is that right?

Adrian
 
Balazs Borbely
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Adrian Bates:

So in my test case where I am forcing it to throw an application exception, DuplicateKeyException, I can catch this and throw an EJBException instead and this will cause a rollback? Is that right?

Adrian



Yes, if your test case is in the transaction scope, I mean the transaction is not finished yet.

But I'd rather catch the exception sin the SessionBean's method and make explicitly the setRollbacOnly call than throw a RuntimeException. Throwing a RuntimeException is not a good practice.

Here you have a session bean mehod example with exception handling.
 
Roger Chung-Wee
Ranch Hand
Posts: 1683
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Throwing a RuntimeException is not a good practice.


What is you reason for saying this?
 
Balazs Borbely
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Roger Chung-Wee:

What is you reason for saying this?



In my opinion all application exceptions (Business logic) exceptions should be checked exceptions.

Because, the client should be aware about the fact that the methods can throw an exception and be able to handle that exception.

In EJB if you throw a runtime exception the transaction will be rolled back, but maybe the business logic requires other handling...
For example:
In a method withdraw(500) if an InsufficientFundsException is thrown, you could withdraw as much as you can and go further. BUT if InsufficientFundsException
is unchecked the transaction is already set for rollback....

see the discution from: http://www.theserverside.com/news/thread.tss?thread_id=30911
 
Roger Chung-Wee
Ranch Hand
Posts: 1683
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

In my opinion all application exceptions (Business logic) exceptions should be checked exceptions.

Because, the client should be aware about the fact that the methods can throw an exception and be able to handle that exception.


This is as per the EJB spec, so no argument here.

In EJB if you throw a runtime exception the transaction will be rolled back, but maybe the business logic requires other handling...
For example:
In a method withdraw(500) if an InsufficientFundsException is thrown, you could withdraw as much as you can and go further. BUT if InsufficientFundsException is unchecked the transaction is already set for rollback....


It would be poor design to make InsufficientFundsException a RuntimeException when the client can recover from this.

The most obvious reason to invoke setRollbackOnly() is when you do not wish the transaction to commit when an application exception is thrown. Most likely, it because an update has already been done in the transaction. So, if your code throws application exception DuplicateKeyException and you want to rollback, you handle the exception by invoking setRollbackOnly() and then rethrowing DuplicateKeyException. Your searchLang method is an example.

I would like to clarify this comment of mine.

Check that your code is not throwing a checked exception, eg SQLException. If so, wrap it in EJBException and throw this exception.


This is better rewritten as follows.

Check that your code is not throwing a checked exception which is not an application exception, eg SQLException. If so, wrap it in EJBException and throw this exception.


If you allow SQLException to propagate to the container, it will be thrown to the client - who will not know what to do with it. This is why checked exceptions (SQLException being a common example) which are unexpected should be encapsulated in EJBException and thrown.

Remember, an application exception is always a checked exception but a checked exception is not always an application exception.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic