aspose file tools*
The moose likes EJB and other Java EE Technologies and the fly likes Transaction EJB session bean Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » EJB and other Java EE Technologies
Bookmark "Transaction EJB session bean" Watch "Transaction EJB session bean" New topic
Author

Transaction EJB session bean

raj joe
Ranch Hand

Joined: Mar 17, 2005
Posts: 99
I have a the following archieture.

Action - session facade (stateless session bean)- DAO - DB.

In my session bean ejb.xml I have set the following
Isolation level (READ COMMITED)
Transcation required as yes
container managed.

I am calling the my DAO methods from the session bean,in my DAO I look up for JDBC datasource and get connection.

My Question
If in one session bean method I call say three methods of a DAO(One updates records and other two inserts data).In all these DAO methods I get seperate DB connections.Will session bean roll back transcation if any one method in DAO has problem (Say problem in last DAO method).

Will it actually rollback the updates issued by first DAO call and inserts issued by second DAO call.
Valentin Tanase
Ranch Hand

Joined: Feb 17, 2005
Posts: 704
To answer to your question, I would say yes the container will roll back the transaction properly. The reason I�m saying this is because the container doesn�t use connection objects in order to demarcate transaction. Moreover, if you try to use either one of Connection.commit()/rollback() methods with CMT then the container will throw an exception. The container has its own transaction management logic, which is mostly based on JTA/JTS api and its intend is not only to provide transactional context to your jdbc calls, but to start global transaction as well.
However not this is the point here. The point is that having different connections for different methods is a very bad design decision. First you need to reserve three connections from the pool for each transaction. Second if one method fails you might not be able to return the other connections to the pool. Hence you�ll get connection leaks as well. My advice to you is to review your design. Override other methods in your DAO to accept a connection parameter and pass the same connection all along the line to all methods.
Regards.


I think, therefore I exist -- Rene Descartes
Bhanu
Ranch Hand

Joined: Dec 05, 2004
Posts: 48
Valentin ,
I don't agree your comments on taking 3 connections vs single connection...passing connection to DAO....blabla...
PN:
Connections will be taken when required and released when done. Those will not be held for future requirements in DAO.

reason: DAO is there to abstract all the DB related stuff(connections/statements...blabla) to the Calling Component. That is the right design pattern they are using. And there is no need to pass connections accross methods.There is no need to alter any thing what they are doing.

If you are holding a connection to execute various operations with DB may not prove efficient. Reason is: after executing one operation, you would do some other stuff before going for another DB operation. But the connection is withheld by you in between which is defeating the purpose of Pooling concept.
[ May 04, 2005: Message edited by: Bhanu P Jasthi ]

Thanks,<br />Bhanu<br />SCEA Step-I<br />SCBCD for J2EE 1.3<br />SCJP1.4
Valentin Tanase
Ranch Hand

Joined: Feb 17, 2005
Posts: 704
Hi Bhanu,

Thank you for your prompt answer.
Well, what I was thinking is this. For simplicity let�s suppose that the DAO has three methods: a(), b() and c(). The clients call the doSomeBusinessLogic on the bean, which invokes all three methods of DAO in this order:

Please notice that I�m not defining business methods that take connections as input parameters, obviously because I don�t want to coupe the business logic and the data access layers. Now let�s admit that a() gets a connection from pool in order to do access the database and b() and c() does the same. So the transaction starts after invoking doSomeBusinessLogic(). The client reserves three connections from the pool, in order to execute the transaction and this just doesn�t look right to me. Now let�s suppose that b() gets an exception. Obviously the connection will be closed inside of b()�s finally block. But how about the connection opened in a()? Who will close that connection?
My suggestion was to overload a(), b() and c() to take one more parameter of type Connection and pass that connection from a to c.
Regards.
Roger Chung-Wee
Ranch Hand

Joined: Sep 29, 2002
Posts: 1683
Why can't a(), b() and c() each obtain a Connection and close it in a finally block? After all, you will usually want to close a Connection as soon as possible so that it can be returned to the pool.


SCJP 1.4, SCWCD 1.3, SCBCD 1.3
Sreenivasa Majji
Ranch Hand

Joined: Jul 12, 2001
Posts: 224
Here is the scenario.

You have 3 DAOs (A, B, C) and with some operations and each operation gets it's own connection and closes it in finally block and each of these method has it's own commit opertion.

Now you have a business method which executes these 3 methods and in the middle of the business method some exception occured and you want to rollback.

Ex:
transcation started.

A.insertSomething();
B.updateSomething();
C.updateSomething();

trnsaction ended.


My questions are:
1) Can each method give commit operation on connection object?
2) If the answer is yes on 1st queston, what happens when B.updateSomething() throws an exception and you want to rollback A.insertSomething()

does it rollback()? If so how?

Thank you for your advice.


Sreenivasa Majji
Valentin Tanase
Ranch Hand

Joined: Feb 17, 2005
Posts: 704
Hi Roger,
Thank you for your reply.

Why can't a(), b() and c() each obtain a Connection and close it in a finally block? After all, you will usually want to close a Connection as soon as possible so that it can be returned to the pool.

Yes of course they can, but the issue is that open/close connection is not always coming for free. Sometimes the container could give you the option to check a connection before getting/returning it to the pool. That basically means that the container will issue a sql like "select sysdate from dual", to check if the connection is healthy. Hence there might be some overhead with this. Another point is that it�s better to reserve the connection for the entire transaction. Imagine that after finishing a() there is no connection available in the pool and the transaction will halt in order for b() to get a connection. This transaction might reserve database locks as well. Finally there are situation where it could be conceivable that private business methods to be able to share a connection. It happened several times in our projects though.
Regards.
Valentin Tanase
Ranch Hand

Joined: Feb 17, 2005
Posts: 704
Hi Sreenivasa,

If you use BMT then you have two solutions: either to use jdbc transactions (using commit/rollback methods on the Connection object), or to use jts/jta transactions (using the UserTransaction object). If you chouse jta, then your dao classes cannot commit a transaction using Connection.commit(), because an exception will be thrown. You have to use UserTransaction.begin()/Commit()/rollback(). If you do that then you�ll design nested transactions and this is not supported by j2ee either. Hence with BMT your design is limited to use jdbc transactions. In that case, if each one of these methods commits the transaction, then it�s nothing much you can do about. They are independent transactions and one commits/rollback without caring much about the others.
Finally if the container manages the transaction (using CMT) then your code is not allowed to commit transactions at all. By doing so the container will raise an exception.
Answering to your questions I would say 1) yes, 2) no.
Regards.
Bhanu
Ranch Hand

Joined: Dec 05, 2004
Posts: 48
I agree there is some overahead involved...but in the process making things uniformly in a better structured manner...that's a tradeoff to take up.

If I were to architect the Data Access stuff...I would do as follows
I would create an abastract DAO which will be extended for different datasources( Oracle/Sybase/UDB/DB2 etc)...
In nutshell, I'll make the DAO using Bridge pattern. AbstractDAO defines core methods( insert/update/delete/run query/run stored proc etc) and concrete DAO( OracleDAO,SybaseDAO) will override them when and where needed.

On top of them, I�ll require my business components to use Data Access components that make use of the concrete DAO�s ( Created using AbstractFactory) to do the database operations.

Buz Comp <----Inputs--> DAC <---->DAO <---> JDBC

DAO should not leak any Datasource specific stuff and should be generic and customizable for each business component.

DAC can be constructed for each buz component.it's a helper to buz component.

"always release a connection as soon as you are done with that and take when you need it. Don't hold it."
Tradeoff's are there....but go for a better if there is no best.
You would have got what I wanted to convey....
Sreenivasa Majji
Ranch Hand

Joined: Jul 12, 2001
Posts: 224
Originally posted by Valentin Tanase:
Hi Sreenivasa,

If you use BMT then you have two solutions: either to use jdbc transactions (using commit/rollback methods on the Connection object), or to use jts/jta transactions (using the UserTransaction object). If you chouse jta, then your dao classes cannot commit a transaction using Connection.commit(), because an exception will be thrown. You have to use UserTransaction.begin()/Commit()/rollback(). If you do that then you�ll design nested transactions and this is not supported by j2ee either. Hence with BMT your design is limited to use jdbc transactions. In that case, if each one of these methods commits the transaction, then it�s nothing much you can do about. They are independent transactions and one commits/rollback without caring much about the others.
Finally if the container manages the transaction (using CMT) then your code is not allowed to commit transactions at all. By doing so the container will raise an exception.
Answering to your questions I would say 1) yes, 2) no.
Regards.


Thank you for the explanation Valentin.

Imagine I am using CMT.
Then what I have to do in the DAOs?
Just get the connection, and perform some update/insert and close the connection? No commt/rollback in DAOs?

If so, when the commit will occur?

If there are no exceptions/errors the transaction commits itself automatically???

I am trying to understand CMT,JDBC,BMT and JTA transactions how they all work together.

Thank you.
Valentin Tanase
Ranch Hand

Joined: Feb 17, 2005
Posts: 704
Hi Sreenivasa ,

Imagine I am using CMT.
Then what I have to do in the DAOs?
Just get the connection, and perform some update/insert and close the connection? No commt/rollback in DAOs?

That’s correct. Actually the next calls are not allowed with CMT, because they can interfere with the container’s transaction boundaries:
  • The commit, setAutoCommit, and rollback methods of java.sql.Connection
  • The getUserTransaction method of javax.ejb.EJBContext
  • Any method of javax.transaction.UserTransaction



  • If so, when the commit will occur?

    The container commits transactions automatically. The transaction boundaries are set through deployment descriptors for each method, using transaction attributes.

    If there are no exceptions/errors the transaction commits itself automatically???

    That’s correct. If the bean throws a RuntimeException then the transaction will also be rolled back automatically. If application specific exceptions are thrown, then is the bean’s responsibility to roll back the transaction.

    I am trying to understand CMT,JDBC,BMT and JTA transactions how they all work together.

    Good luck, you are on the right track.
    Regards.
    Valentin Tanase
    Ranch Hand

    Joined: Feb 17, 2005
    Posts: 704
    Hi Bhanu,

    It sounds like a great design. Overloading every method and providing a version that can take a connection cannot hurt either. You never know when DAO’s clients might need it.
    However these days there is no "market" for DAO patterns. Hibernate or any other ORM tool is a much better choice. Tomorrow after releasing ejb3 probably entity ejbs will became the preferable choice for j2ee community, or at least this is my hope.
    Regards.
    raj joe
    Ranch Hand

    Joined: Mar 17, 2005
    Posts: 99
    Originally posted by Valentin Tanase:
    Hi Sreenivasa ,

    Good luck, you are on the right track.
    Regards.


    Valentin

    As mentioned earlier if I am using the Below archieture.
    Action - Session Bean - DAO -DB

    I have decided to manage my transcation using session bean.
    But as you said container rolls back the transcation only on occurance of
    a Run Time Exception (that is probably SQLException)

    But I have many checked Application Exceptions thrown by my DAO.
    In this case I have to handle the tanscation.(How do i do it in session bean to rollback the transcation on my application exceptions)
    Roger Chung-Wee
    Ranch Hand

    Joined: Sep 29, 2002
    Posts: 1683
    This may be useful..http://www.coderanch.com/t/316284/EJB-JEE/java/Remote-Exception
    The only time you will want to handle an application exception is if you know that the client does not expect it and/or cannot recover from it. In such a case, wrap the application exception in javax.ejb.EJBException and throw it. Otherwise, which should be most of the time, just duck the application exception and let the client deal with it.
    Robert Strong
    Ranch Hand

    Joined: Sep 10, 2002
    Posts: 84
    hi Valentin:

    one more question, suppose I use CMT in Stateless SessionBean, which wrap several DAO methods: DAO.a(), DAO.b(), DAO.c().

    if I called a stored procedure in DAO method DAO.b(), and the database transaction was committed at the end of this stored procedure, later DAO.c() raise a RuntimeException, then Container would rollback the transaction, but would it be able to rollback the already commited database transaction in the stored procedure called by DAO.b()?

    thanx
    Roger Chung-Wee
    Ranch Hand

    Joined: Sep 29, 2002
    Posts: 1683
    The result of mixing stored procedure commits and JTA commits is highly unpredictable, so must be avoided.
    Valentin Tanase
    Ranch Hand

    Joined: Feb 17, 2005
    Posts: 704
    Hi Raj,

    As mentioned earlier if I am using the Below archieture.
    Action - Session Bean - DAO -DB

    I have decided to manage my transcation using session bean.
    But as you said container rolls back the transcation only on occurance of
    a Run Time Exception (that is probably SQLException)

    But I have many checked Application Exceptions thrown by my DAO.
    In this case I have to handle the tanscation.(How do i do it in session bean to rollback the transcation on my application exceptions)

    Robert has a good point.
    Another option to consider is using the SessionContext.setRollbackonly() to rollback the transaction. You might code your bean methods like this:
    Valentin Tanase
    Ranch Hand

    Joined: Feb 17, 2005
    Posts: 704
    Hi Robert,

    if I called a stored procedure in DAO method DAO.b(), and the database transaction was committed at the end of this stored procedure, later DAO.c() raise a RuntimeException, then Container would rollback the transaction, but would it be able to rollback the already commited database transaction in the stored procedure called by DAO.b()?

    The only way you can know exactly what will happen is to try this yourself. Whether the container initiated transaction and the SP transaction are executed within the same transactional context or they are independent transaction, I don�t know. I never tried something like this and I agree with Roger that the result is unpredictable.
    If you aim to achieve better performances using SP then you might consider implementing the entire transaction management through SPs. Your app won�t be able to take the advantage of global transactions in this case, but this might be ok if your app doesn�t require it.
    Sreenivasa Majji
    Ranch Hand

    Joined: Jul 12, 2001
    Posts: 224
    Thank you all the great replies.

    I have been struggling to get reliable answers long time, now I knew where to look for the right answers.

    Great job.

    Thank you.
    raj joe
    Ranch Hand

    Joined: Mar 17, 2005
    Posts: 99
    Originally posted by Roger Chung-Wee:
    This may be useful..http://www.coderanch.com/t/316284/EJB-JEE/java/Remote-Exception
    The only time you will want to handle an application exception is if you know that the client does not expect it and/or cannot recover from it. In such a case, wrap the application exception in javax.ejb.EJBException and throw it. Otherwise, which should be most of the time, just duck the application exception and let the client deal with it.


    Roger

    If I throw all my application exception to client ,how would the client roll back the transcation started by the sesion bean

    can i use the below code in client program that call the session bean method.

    public void clientMethod()
    {
    try
    {
    call Session Bean method

    }
    catch (ApplicationException Ex)

    {
    sessionContext.setRollbackonly(); // Will i get the sessionContext in my client pgm
    }
    Roger Chung-Wee
    Ranch Hand

    Joined: Sep 29, 2002
    Posts: 1683
    By definition, an application exception is expected by the client, so will therefore be handled by the client. You only need to rollback those transactions which cause a condition which the client neither expects nor can recover from.
    Valentin Tanase
    Ranch Hand

    Joined: Feb 17, 2005
    Posts: 704

    Thank you all the great replies.

    I have been struggling to get reliable answers long time, now I knew where to look for the right answers.

    Great job.

    Thank you.


    You.re very welcome Sreenivasa. I�m glad I could help
    Pradeep bhatt
    Ranch Hand

    Joined: Feb 27, 2002
    Posts: 8919

    It is not a good practice to pass Connection object to DAO methods. What is the purpose of DAO ? To hide the details from where the data is obtained. Today the database is Oracle , tomorrow it could DB2. If the connection is passed from Session bean to DAO, they the Session bean code has to be changed to lookup for DB2 DataSource rather than a Oracle datasource. Since connection pooling is used , better to lookup for Datasource in each method and close the connection in the finally block.

    You need to tune the connection pool if the pool size is not sufficient.


    Groovy
    Roger Chung-Wee
    Ranch Hand

    Joined: Sep 29, 2002
    Posts: 1683
    Actually, you will never pass a Connection object to a DAO method from a bean. The Connection is obtained by the DAO, because the DAO is hiding the implementation of the persistance layer from the business logic layer.

    The debate is whether or not a Connection should be passed from one DAO method to another DAO method. I'm inclined to close the Connection in each method and get another Connection when needed. I understand what Valentin is saying about not getting connections for free, but this is container-dependent and performance issues cannot easily be foreseen. If it turns out that there is a problem with my approach, then I'll consider various solutions, which would include tuning the container's connection pooling system and passing the connection from method to method.
    Pradeep bhatt
    Ranch Hand

    Joined: Feb 27, 2002
    Posts: 8919

    Sorry I misunderstood the problem. In the ejb-jar file you can set the Datasource with a shareable value for res-sharing-scope so that the container returns the same connection in a transaction.
    From spec

    [ May 10, 2005: Message edited by: Pradip Bhat ]
    raj joe
    Ranch Hand

    Joined: Mar 17, 2005
    Posts: 99
    Originally posted by Valentin Tanase:

    You.re very welcome Sreenivasa. I’m glad I could help


    Some of my transcations are global and some are not.

    In my stateless session bean ejb.xml file can i say that for some methods in session bean i want the container to manage the transcations as they are global and for other session bean methods disable transcation.
    raj joe
    Ranch Hand

    Joined: Mar 17, 2005
    Posts: 99
    Originally posted by Valentin Tanase:

    You.re very welcome Sreenivasa. I’m glad I could help


    How can i define a transcation boundary if I am using the below archieture
    Action-Session bean-DAO-DB

    How do i define transcation boundry in this case.
    Without using Spring or any other frameworks.
    Valentin Tanase
    Ranch Hand

    Joined: Feb 17, 2005
    Posts: 704
    Hi Raj,

    In my stateless session bean ejb.xml file can i say that for some methods in session bean i want the container to manage the transcations as they are global and for other session bean methods disable transcation.

    If you have methods that don�t need transactions, then you can always use the TX_NOT_SUPPORTED attribute. This way the transaction will be suspended while your method executes and resumed after that. If you specify a transaction attribute for the entire enterprise bean and another transaction attribute for a particular method, then the attribute for the method takes precedence.

    How can i define a transcation boundary if I am using the below archieture
    Action-Session bean-DAO-DB

    How do i define transcation boundry in this case.
    Without using Spring or any other frameworks.

    As a rule of thumb, when designing transactions with EJBs is always better to start with CMT. After all what is the implicit middleware good for? J2EE spent so much time and effort to standardize all these services that it would be a shame to build a J2EE application and ignore them. However we know that J2EE and EJBs are not solutions for every problem. If for example your app requires nested transactions, then you might consider other solutions.
    Assuming that the J2EE transactional model is satisfactory for your app, then I would define the transactions boundaries within the ejb layer. Ideally I would use CMT and let the container do what the container knows to do best: provide implicit middleware services.
    Finally I�d like to remind you that each system is different and requirements are different as well. I remember building an EJB business layer for a bank, using SLSBs that did not implement any type of transaction management. This business services had to replace an old client-server legacy application. Because the bank wanted to keep the old client that initiated the transactions, we had to rely on an EJB design where only client-managed transactions are allowed; against all odds.
    Regards.
    Roger Chung-Wee
    Ranch Hand

    Joined: Sep 29, 2002
    Posts: 1683
    In my stateless session bean ejb.xml file can i say that for some methods in session bean i want the container to manage the transcations as they are global and for other session bean methods disable transcation.

    For a CMT session bean, you need either the NotSupported or Never transaction attribute. For the former, the container will suspend the transaction (if it exists) whilst executing the method, for the latter it is a requirement that the client calls without a transaction context.

    Here is an example of what is needed in the deployment descriptor.
     
    Don't get me started about those stupid light bulbs.
     
    subject: Transaction EJB session bean