-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 18 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Problem understanding transaction
PostPosted: Thu Mar 04, 2004 4:22 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
hi all,
i've made an error thinking begin / commit transaction was unecessary in certain cases.
It seems many have done the same error.
To prevent this, i'd like to discuss about several cases.
I know this more a "db" knowledge but i think the forum can help much better.
the questions may look idiot but...

So i begin:
1- we see in the examples in the doc that it is a best practice to always use transaction even if we only make a "select", but is there a difference between:
1-a
sess = sf.openSession();
Transaction tx = sess.beginTransaction();
// execute some queries....
sess.find("from Cat as cat left outer join cat.kittens kitten");
....
tx.commit();

1-b
sess = sf.openSession();
// execute some queries....
sess.find("from Cat as cat left outer join cat.kittens kitten");
....
sess.connection.commit();

2- as it seems to be a best practice to always consider using connection.transaction, what about changing the servlet filter (open session in view http://www.hibernate.org/43.html, modifications are in red

/**
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
if (hibernateHolder.get() != null)
throw new IllegalStateException(
"A session is already associated with this thread! "
+ "Someone must have called getSession() outside of the context "
+ "of a servlet request.");

try
{
chain.doFilter(request, response);
}
finally
{
Session sess = (Session)hibernateHolder.get();
if (sess != null)
{
hibernateHolder.set(null);

try
{
session.connection().commit(); // and in this case, what happens if a rollback() has occured before?
sess.close();
}
catch (HibernateException ex) { throw new ServletException(ex); }
}
}
}

/**
* ONLY ever call this method from within the context of a servlet request
* (specifically, one that has been associated with this filter). If you
* want a Hibernate session at some other time, call getSessionFactory()
* and open/close the session yourself.
*
* @return an appropriate Session object
*/
public static Session getSession() throws HibernateException
{
Session sess = (Session)hibernateHolder.get();

if (sess == null)
{
sess = factory.openSession();
hibernateHolder.set(sess);
}
session.beginTransaction();

return sess;
}



Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 4:44 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
You should always use transactions, always, always :)

Thats not a good example for transaction handling in a servlet filter. Look at AdminApp for a better one.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 7:03 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
ok i'm looking the AdminApp.
As i've never worked with opensymphony.xwork,
can someone tell the role of import com.opensymphony.xwork.interceptor.Interceptor;

Something like a servletFilter?

And about HibernateSession, the use of setRollBackOnly() is to manage what will happen when the interceptor dispose() method used, isn't it?



Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 8:12 am 
Newbie

Joined: Thu Nov 13, 2003 12:03 pm
Posts: 18
Location: France
[quote]You should always use transactions, always, always :)[/quote]
In my case, I use EJB SessionBeans, to have container managed transactions.
I don't understand why a transaction as to be open if the service is in "Supports" or "Never" transaction demarcation mode ( means only selects will be performed ).


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 8:19 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
I don't know how people get the impression you should not manage transactions for "read-only" operations. Of course you should do all related reads in a transaction, otherwise you will get nice problems.

In fact, there is no such thing as "no transaction", your database access will always be in a transaction. If you don't use a CMT transaction, and do database access, you will get a transaction nevertheless, only it won't be managed by the container. The only consequence of this is that most likely you will get a commit after every statement (autocommit)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 3:20 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
someone to explain about adminApp?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 3:48 pm 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
pierre-yves wrote:
Quote:
You should always use transactions, always, always :)

In my case, I use EJB SessionBeans, to have container managed transactions.
I don't understand why a transaction as to be open if the service is in "Supports" or "Never" transaction demarcation mode ( means only selects will be performed ).


If you do not need transaction, you do not need DB too, concurency control is the most important RDBMS feature, there are a lot of faster ways to search data without RDBMS.
For some concurency control algorythms even readonly transaction must be commited to release read locks. Transactions are used to isolate readers from writer to produce serial execution history, recovery, performance for concurent access ....
Before to use RDBMS you need to know about concurency control implementation , It sound evil, but it is true if you develop "mission critical" applications, you need to know about conflicts, deadlocks and serialization failures in concurency control algorythm (it depends on RDBMS implementation).
It is very dangerous to think in "Supports", "Never" terms, both read and write operations are important for concurency control in the same way.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 5:59 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
yes yes yes,
i wrote the topic to prevent everybody TO ALWAYS USE transactions, pierre-yves did the same mistake many people are doing, michael told me about AdminApp, i've noticed the classes that may help managing transaction so anyone can respond my previous questions, it is related to threadLocalSession that a lot of people are using?

Thanks,
Anthony


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2004 2:22 am 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
ThreadLocal is a good way to store things like session, it is nothing whrong
to store it on thread call stack (method parameter), request attribute is not so bad place for session too. You can think session and transaction are the same object, it helps to understand hibernate objects.
Transaction demarcation in filter is a good way, it can work for all of web applications I can ever saw.
I do not see problems in your code too, probably it need some cleanup to fix exception handling, add
"finally" blocks, but idea is good.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2004 3:49 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
thanks a lot, do you think it's a good idea to complete this example and put it on http://www.hibernate.org/43.html.
I think people using ThreadLocal must have seen this page, so by putting comments on the transactionnal related code lines, users won't make the mistake about transaction...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2004 5:13 am 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
Transaction per thread is a very old way, it is was invented before ThreadLocals in JAVA, probably it is not the best way, but it works (it is proven in practice).
Use "lazzy" connections, never open connection for close or commit ! And always commit/abort it if it was opened by thread.

BTW Use nested "try" blocks, it is more clear:


Code:
Resource1 r1 = open();

  try{

        Resource2 r2 = r1.open();
       
         try{

          //use r2
           
          return result;

        }finally{
             
               r2.close();
       
         }


   }finally{

      r1.close();

  }


You do not need "if(r1 != null) ... if(r2 != null)" if you write exeption handling code this way.


Top
 Profile  
 
 Post subject: Session Bean container managed transaction
PostPosted: Fri Mar 05, 2004 5:32 am 
Beginner
Beginner

Joined: Wed Mar 03, 2004 6:02 am
Posts: 46
Location: Kuala Lumpur, Malaysia
If I am already using container managed transaction on my session bean methods;
do I still need to use the Transaction class from Hibernate ?

Thanks

alistair


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2004 6:09 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
You don't need to, but you can. If you don't use it, you have to flush manually.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2004 6:16 am 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
I think you do not need hibernate transaction object with CMT, hibernate needs to know transaction demarcation for cache, but it uses container specific strategy to find transaction manager and you do not need to demarcate transaction for hibernate if it is well configured.
You need it in CMT if you do not use "TransactionManagerLookupStartegy"
and if you use custom transaction synchronization callback (Stateful session bean).
I think it is a good way to use Stateful session bean and to demarcate transaction on client, but you need to manage this bean the same way as hibernate session, session bean and user transaction per thread, lazzy create/remove, UserTransaction begin/commit in filter.
It is a way to map client thread and server transaction (distributed transactions). I do not use distributed transactions myself, just experimented, my use cases are more simple for production, so it is a good way in theory and I am not sure it works good in practice (it depends on container quality).


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2004 8:18 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
and what is the best on the doFilter() method sess.close(); or session.disconnect?


I understand that session.close() is more expensive than disconnect because it means that the next need will have to open a new jdbc connection instead of reusing one of the pool. Am I right?

So if the connexion pool is well configured, we may only disconnect the session in the filter no?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 18 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.