Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Transaction context propogation  RSS feed

 
Harish Verma
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am attempting to include transactions in my J2EE app.

I have a stateless session facade bean that calls various methods in a POJO DAO object. I have declared that the facade bean's method requires the transaction attribute RequiresNew. _context is my SessionContext object.

This method will then call POJO object that impplements my persistence logic, including stored procedures.

When this method returns, I will call _context.setRollbackOnly(); in case of any errors.

The prob is the transaction does not rollback; could it be that the DAO object, being POJO, does not execute under the transaction context started by the session bean? That is, a session bean's UserTransaction is only obeyed by another EJB bean, and not POJO? If not, pls explain why the transaction does not rollback when I call _context.setRollbackOnly().

Could someone pls explain the basics of transaction mechanism, or post good links to the same.
[ March 23, 2006: Message edited by: Harish Verma ]
 
Jaikiran Pai
Sheriff
Posts: 10447
227
IntelliJ IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When you say that the transaction does not rollback, do you mean to say there are any exceptions thrown or is it that the data that you manipulated in the database is not getting rolled back? If it is the latter, how are you doing the database operation? You should be using a Datasource to do database operations, so that it get involved in the transaction intiated by the container
 
Harish Verma
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by jaikiran pai:
When you say that the transaction does not rollback, do you mean to say there are any exceptions thrown or is it that the data that you manipulated in the database is not getting rolled back? If it is the latter, how are you doing the database operation? You should be using a Datasource to do database operations, so that it get involved in the transaction intiated by the container


Jaikiran: Pls re-read my question above; I have corrected an error.

The data manipulated is not rolledback. I am simulating an error, and expect that calling _context.setRollbackOnly(); will discard the changes I made to the database. The rollback never happens, though I have properly declared CMT in the ejb-jar.xml

Is this happening because the DAO object is POJO and does not know about the sesison bean's container-initiated transaction? If this is true, I am stuck with only JDBC transaction to control my DAO code.

Also, I tried this:

1. Disabled CMT, by declaring bean-managed transaction in ejb-jar.xml

2. In the session (facade) bean:

UserTransaction utx = ctx.lookup("java:comp/UserTransaction");

With the utx, utx.begin() to initiate, and utx.rolback(); to rollback if an exception is thrown in POJO DAO bean.

Again, the changes are not rolledback. So: is the transaction context not propogating to the POJO at all?
[ March 23, 2006: Message edited by: Harish Verma ]
 
Thomas Taeger
Ranch Hand
Posts: 311
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Harish Verma:
The data manipulated is not rolledback.


i hardly dare to ask but: Is AutoCommit set to true anywhere?
 
Harish Verma
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Thomas Taeger:


i hardly dare to ask but: Is AutoCommit set to true anywhere?


Excuse my ingorance, but when I am not using JDBC transactions, do I still have to bother with setAutoCommit(false)? I thought if you use CMT, you dont have to. Correct me if I am wrong.
 
Roger Chung-Wee
Ranch Hand
Posts: 1683
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please post your code and DD.

What server are you using?
 
Jaikiran Pai
Sheriff
Posts: 10447
227
IntelliJ IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The data manipulated is not rolledback

How are you doing the database related stuff? Are you using a transactional datasource or are you using normal JDBC APIs?
You will have to use transactional datasource, so that the data manipulated is rolled back, when the EJB initiated transaction rolls back.

Is this happening because the DAO object is POJO and does not know about the sesison bean's container-initiated transaction

If your POJO does some activity involving a transaction aware resource then that operation is ALSO involved in a transaction.
 
Harish Verma
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Roger Chung-Wee:
Please post your code and DD.

What server are you using?


Version 1: Using BMT session bean:

In session bean:

public ArrayList viewEmployee(...) throws BusinessException, Exception {

//get the Usertransaction.
Context initCtx = new InitialContext();
UserTransaction utx = (UserTransaction) initCtx.lookup("java:comp/UserTransaction");

//Get the Ds for DAO object.
javax.sql.DataSource dataSource =
(javax.sql.DataSource)context.lookup("jdbc/DBConnection1CoreDS");

connection = dataSource.getConnection();

//Create the POJO Dao object. The object will store conn as an instance member.
empDAO = new EmployeeDAO(conn, employeeBean, errorList);


try{
utx.begin();

//This is the call to DAO method.
empDAO.select();

//All OK.
utx.commit();
}

catch(BusinessException b){
utx.rollback();

System.out.println("Facade: BusinessException was caught in viewEmployee().");

throw new BusinessException(b.getMessage());
}

catch(Exception b)
{
utx.rollback();

System.out.println("Facade: Exception was caught in viewEmployee(): " + b.getClass());

throw new Exception(b.getMessage());
}



}

The DAO method select() simply fires 3 insert statements, in which the last one is sure to fail � wrong field name.

The table is very simple � employee table with 3 fields.

Version 2: Using CMT session bean:

Ejb-jar.xml updated to include transaction boundary for bean method service() that calls viewEmployee().

The catch(BusinessException) and catch(Exception) handlers are updated with:

_context.setRollbackOnly();

In place of:

utx.rollback();

Both versions 1 and 2 fail to rollback.

I am using Oracle JDeveloper 10g and Oracle DB.
 
Roger Chung-Wee
Ranch Hand
Posts: 1683
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you get a JDBC connection from an incorrectly configured DataSource, it will not participate in the EJB container transaction. Check your documentation about this.

Also, you are using an instance connection variable. This is not good practice - make it local.
 
Thomas Taeger
Ranch Hand
Posts: 311
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Harish Verma:

when I am not using JDBC transactions, do I still have to bother with setAutoCommit(false)? I thought if you use CMT, you dont have to.


... not by setAutoCommit(...) / JDBC but as a database option. I thought there was something like that at least in Oracle, otherwise please forget about.
 
Babji Reddy
Ranch Hand
Posts: 106
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try keeping a connection.close() in the finally{} block.
Probably the connection since is remained open, and hence not yet returned to the connectionpool, is holding to the commit/rollback to happen
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!