-->
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.  [ 4 posts ] 
Author Message
 Post subject: Spring Transactions with Hibernate
PostPosted: Mon Nov 10, 2003 2:44 pm 
Beginner
Beginner

Joined: Wed Oct 15, 2003 3:08 pm
Posts: 32
Ok, so this might not be so much a Hibernate question as a Spring one. Spring talks about using a TransactionTemplate or an AOP TransactionInterceptor to manage transactions. Those are fine if you want to manage transactions at the DAO layer, but I don't.

Instead, I want to maintain these transactions at a Service layer, which sits on top of my DAO and DO objects. So, I want to use the PROPOGATION_MANDATORY option. It is not clear how I begin and end transactions in this mode. It seems like I shoulse use PlatformTransactionManager directly, but the docs specifically state that is shouldn't be used, but TransactionTemplate or AOP TransactionInterceptor should be used instead.

Unfortunately, all of the samples seem to avoid this issue :/.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 10, 2003 6:28 pm 
Newbie

Joined: Tue Aug 26, 2003 9:45 am
Posts: 17
Location: Toronto, Canada
You have misunderstood where and how TransactionTemplate and TransactionInterceptor should be used.

They are _not_ meant to be used in and around (respectively) DAO objects, but in and around (respectively) service layer objects, exactly as you need.

I am not going to repeat the code from the article here:
http://www.hibernate.org/110.html
but please take another look at it

If you're still unclear I'll be more than happy to go into more detail.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 10, 2003 6:50 pm 
Senior
Senior

Joined: Wed Aug 27, 2003 6:04 am
Posts: 161
Location: Linz, Austria
TransactionTemplate and TransactionInterceptor are not at all tied to the DAO layer. They are rather exactly targetted at a service layer that sits on top of DAOs. Effectively, it doesn't matter at which level you apply them. You can nest them as deeply as you want, i.e. make your service layer transactional and let it delegate to a DAO layer that is again transactional. Spring-managed transactional code will automatically participate in existing transactions, you don't have to worry about that.

It's similar to EJB CMT in that the "propagation behavior" determines what will actually happen. This is a configuration setting: The demarcation code will look exactly the same at all levels, be it TransactionTemplate.execute blocks or proxy definitions for TransactionInterceptor.
- PROPAGATION_REQUIRED will participate in an existing transaction or create a new one for the nested scope else.
- PROPAGATION_MANDATORY will require an existing transaction, i.e. throw an exception else.
- PROPAGATION_SUPPORTS will participate in an existing transaction or execute non-transactionally else.

Generally, transactions are propagated via ThreadLocals underneath. This means that PROPAGATION_SUPPORTS does not do anything specific: Transaction-aware code will automatically participate in existing transactions or execute non-transactionally else in any case. PROPAGATION_REQUIRED is the most common behavior, therefore it is TransactionTemplate's default. Note that this will work with any transaction strategy, be it HibernateTransactionManager, JtaTransactionManager, or any other!

Both TransactionTemplate and TransactionInterceptor support all of Spring's transaction settings, as defined by the TransactionDefinition interface. With TransactionTemplate, you simply invoke setters like setPropagationBehavior and setIsolationLevel, with corresponding constants from the TransactionDefinition interface (which TransactionTemplate implements, BTW). With TransactionInterceptor and TransactionProxyFactoryBean, you specify them as transaction attribute Strings a la "PROPAGATION_REQUIRED,ISOLATION_REPEATABLE_READ".

So the following would work accordingly: When loadStuff gets executed on its own, a new transaction will be created for its scope. When loadStuff gets invoked via doStuff, it will participate in the latter's existing transaction. If you switch loadStuff's propagation behavior to PROPAGATION_MANDATORY, it will still participate in an existing transaction but throw an exception when invoked on its own. Note that in many cases, it is not necessary to put transaction demarcation code in DAOs at all, leaving this completely to the service layer.

Code:
public class MyDataAccessObject {
  ...
  public void loadStuff() {
    TransactionTemplate transactionTemplate = new TransactionTemplate(this.transactionManager);
    transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    transactionTemplate.execute(
      new TransactionCallbackWithoutResult() {
        public void doInTransactionWithoutResult(TransactionStatus status) {
           ...
           // do some data access
           ...
        }
     }       
  }
}

public class MyBusinessService {
  ...
  public void doStuff() {
    TransactionTemplate transactionTemplate = new TransactionTemplate(this.transactionManager);
    transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    transactionTemplate.execute(
      new TransactionCallbackWithoutResult() {
        public void doInTransactionWithoutResult(TransactionStatus status) {
           ...
           myDataAccessObject.loadStuff();
           ...
        }
     }       
  }
}


FYI, I've slightly revised the article at http://www.hibernate.org/110.html today to make a few things clearer. You might want to have another look at the examples there. They still don't discuss transaction nesting, though.

Juergen


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 11, 2003 1:53 pm 
Beginner
Beginner

Joined: Wed Oct 15, 2003 3:08 pm
Posts: 32
Thank you both for your replies. I think I misread one of the examples and thought that the transaction stuff was being done at the DAO layer, but it is exactly where I needed it: in the service layer. Thanks for clearing up my confusion! I look forward to working with Spring :).


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

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.