• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Non-EJB transaction rollbacks

 
Alana Sparx
Ranch Hand
Posts: 121
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The architecture of the project I am working on requires the exposure of a mid-tier service based architecture.

These services are not necessarily fronted by an EJB. The intention is that the whole project could be run in an offline setting using eg SWT (this is a design condition). As such, the business services would need to be able to run using the J2SE runtime rather than the J2EE runtime. The business services therefore cannot reference anything required by the container (as the service may not be running in one). This has implications for rolling back transactions in the event of encountering exceptions as I will be unable to use the EJBContext or UserTransaction to rollback. My query here is, am I looking at implementing my own rollback strategy? And to do this, does that mean if I perform an insert, in the catch block of any exception I need to perform a delete statement; if I perform an update, do I first need to cache a �select� statement of the data to be changed, and in a catch block delete the update and insert the cached �select� statement data? This approach seems to be tiresome, error-prone and quite possibly complicated.

Are there any resources/APIs that can help in this?

Many thanks.
 
Ådne Brunborg
Ranch Hand
Posts: 208
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Have you checked out Hibernate?
[ April 18, 2006: Message edited by: �dne Brunborg ]
 
Ulf Dittmer
Rancher
Posts: 42967
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, you don't need to keep track of all that, or do it in your code. That's what the transaction capabilities of JDBC are for. Check out the Connection.setAutoCommit(false), Connection.commit() and Connection.rollback() methods. With a recent database and driver you can even use savepoints to perform partial rollbacks.
 
Alana Sparx
Ranch Hand
Posts: 121
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanx chaps.
 
Alana Sparx
Ranch Hand
Posts: 121
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Ulf / �dne for your replies. Sorry to drag this topic up again.

If I go down the route of using the transaction capabilities of JDBC:
setAutoCommit(false)
commit()
rollback()

is it also true that I'll need to set the session bean's transaction-type to 'Bean', not 'Container'. This seeems to be the case from the testing I have done (if the bean is set to 'Container', I'm finding that SQL statements are persisted to the database regardless of the setAutoCommit() value and that rollback() has no effect).

If I am correct, why would this be so?

Many thanx
 
Pradeep bhatt
Ranch Hand
Posts: 8927
Firefox Browser Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Alana Sparx:
Thank you Ulf / �dne for your replies. Sorry to drag this topic up again.

If I go down the route of using the transaction capabilities of JDBC:
setAutoCommit(false)
commit()
rollback()

is it also true that I'll need to set the session bean's transaction-type to 'Bean', not 'Container'. This seeems to be the case from the testing I have done (if the bean is set to 'Container', I'm finding that SQL statements are persisted to the database regardless of the setAutoCommit() value and that rollback() has no effect).

If I am correct, why would this be so?

Many thanx


For bean /container managed transaction it is illegal to set autoAutoCommit(false). For BMT, you should JTS usertransaction.rollback(). For CMT, use ejcontext.setRollbackOnly().
 
Alana Sparx
Ranch Hand
Posts: 121
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

For bean /container managed transaction it is illegal to set autoAutoCommit(false).


Then I appear to be experiencing some strange results: here is the deployment descriptor


The EjbPolicyService makes a call to a business service, which ultimately makes a call to a persistence manager, where the following code is encountered in this transaction:


The above runs fine, updating the database. If I generate a runtime exception, it all rollsback as expected.

what's going on?
 
Pradeep bhatt
Ranch Hand
Posts: 8927
Firefox Browser Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What is the tranaction attribute set for the method?
 
Alana Sparx
Ranch Hand
Posts: 121
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Pradip, many thanks for your perseverance

What is the tranaction attribute set for the method?


If the transaction-type is set to 'Bean', why is the above important (and if it is relevant, where do I find these attributes)? Am I reading you correctly if you think that the transaction attribute set for the method should be one of 'Required', 'RequiresNew', 'Mandatory' etc? If so, and this bean's transactions are not container-managed, are these attributes necessary?

Remember that the services I am using can be called from an EJB, but it is conceivable for these services to be deployed outside a container and called by some other client, so I *cannot* rely on container transaction management.

Thanks again
 
Pradeep bhatt
Ranch Hand
Posts: 8927
Firefox Browser Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Alan,

The EJB spec clearly states that in case of Bean managed transaction using resource specific API like connection.commit/jmssession.rollback.

The Bean Provider uses the UserTransaction interface to demarcate transactions. All updates to
the resource managers between the UserTransaction.begin and UserTransaction.commit
methods are performed in a transaction. While an instance is in a transaction, the instance must not
attempt to use the resource-manager specific transaction demarcation API (e.g. it must not invoke the
commit or rollback method on the java.sql.Connection interface or on the
javax.jms.Session interface).



You seem to be doing exactly what the spec says not to do.

To make your code work in both in J2SE and J2EE.I suggest that you use container managed transaction and set transaction attribute to NotSupported and the use JDBC connection API to commit /rollback.
 
Alana Sparx
Ranch Hand
Posts: 121
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ahhh!

Just implemented your suggestions Pradip (TransactionType = Container, Container Transaction = NotSupported) and it works perfectly.

Thanks for all your help & patience
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic