Results 1 to 10 of 10

Thread: TransactionProxyFactory and ApplicationContext

  1. #1
    Join Date
    Oct 2004
    Posts
    9

    Default TransactionProxyFactory and ApplicationContext

    Hi

    I have the following scenario

    I have a webapp in which the web.xml has an applicationcontext created using contextloaderservlet with a set of xml files defining the beans.
    I also refer in the webapp another jar file in which a class creates another applicationcontext using classpathapplicationcontext with a set of xml files definfing beans.

    In one of the scenario a MgrbeanA invoked by a controller in the webapp is obtained from TransactionProxyFactory and the MgrbeanA further calls another MgrBeanB defined in the applicationcontext that was created by the class in the jar file which is also obtained from a TransactionProxyFactory.
    In effect the code looks something like this in the MgrBeanA in the WebApp

    doSomething {
    performActionOneinDB();
    callMgrBeanBInJarToPerformActionInDB();
    performActionTwo();
    }

    The issue i'm facing currently is , if there is an exception raised in performActionTwo() i expect the whole operation being rolled back, but the actually what happens is the callMgrBeanInJarToPerformActionInDB(); is committed irrespective of what happens in MgrbeanA.
    As these are two different applicationcontexts the datasources referred in these contexts are also different.

    Is my approach correct, should i be,
    1. not define datasources seperate if i want to propogate the transaction
    2. merge my application contexts into one
    3. make the application contexts hierarchial

    i tried to read thru the documentation and the forum posts, but i'm not sure of which approach to take..

    also i have another clarification, if i want to have an applicationcontext defined in the webapp so that the cotroller can invoke it, how do i ensure the other applicationcontexts i define will be part of the appcontext i defined in webapp, and how do i access the beans if i dont have servletcontext available else where.

    can any one help me out on this...thanks in advance..

  2. #2
    Join Date
    Aug 2004
    Posts
    1

    Default

    post your applicationContex.xml

  3. #3
    Join Date
    Oct 2004
    Posts
    9

    Default

    This is how my web.xml looks like
    <web-app>
    <display-name>MyWebApp</display-name>

    <description>MyWebApp</description>

    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
    /resources/applicationContext-DataAccess.xml
    /resources/applicationContext-Common.xml
    /resources/applicationContext-Mgr.xml
    </param-value>
    </context-param>

    <servlet>
    <servlet-name>context</servlet-name>
    <servlet-class>org.springframework.web.context.ContextLoade rServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet>
    <servlet-name>webapp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherSe rvlet</servlet-class>
    <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
    <servlet-name>webapp</servlet-name>
    <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    </web-app>

    this is my applicationContext-DataAccess.xml
    <beans>
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.Pr opertyPlaceholderConfigurer">
    <property name="location"><value>classpath:jdbc.properties</value></property>
    </bean>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverM anagerDataSource">
    <property name="driverClassName"><value>${jdbc.driverClassNa me}</value></property>
    <property name="url"><value>${jdbc.url}</value></property>
    <property name="username"><value>${jdbc.username}</value></property>
    <property name="password"><value>${jdbc.password}</value></property>
    </bean>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSou rceTransactionManager">
    <property name="dataSource"><ref local="dataSource"/></property>
    </bean>
    </beans>

    the applicationContext-Mgr.xml defines the MgrbeanA and the applicationContext-Common.xml some support beans
    the following is the definition of the MgrbeanA

    <bean id="MgrbeanA" class="org.springframework.transaction.interceptor .TransactionProxyFactoryBean">
    <property name="transactionManager">
    <ref bean="transactionManager"/>
    </property>
    <property name="target">
    <ref local="MgrbeanATargetBean"/>
    </property>
    <property name="transactionAttributes">
    <props>
    <prop key="*">PROPAGATION_REQUIRED</prop>
    </props>
    </property>
    </bean>

    <bean id="MgrbeanATargetBean" class="com.test.MgrbeanA">
    <property name="appResource">
    <ref bean="appResourceBean"/>
    </property>
    <property name="basicInfoDao">
    <ref local="basicInfoDaoBean"/>
    </property>
    </bean>
    ....

    As i have mentioned earlier, in the method doSomething() in MgrbeanA, calls MgrBeanB which is in a jar file.
    It gets the MgrBeanB from a static class in the jar MyBeanProvider, which looks like this


    public static ApplicationContext ac;
    public static final String CONFIG_LOCATION_PATH = "classpath:";

    protected static void initApplicationContext() {
    ArrayList locs = new ArrayList();

    locs.add( CONFIG_LOCATION_PATH + "applicationContext-DataAccess.xml" );
    locs.add( CONFIG_LOCATION_PATH + "applicationcontext-OtherMgrs.xml" );
    locs.add( CONFIG_LOCATION_PATH + "applicationcontext-Support.xml" );

    ac = new FileSystemXmlApplicationContext( (String[]) locs.toArray( new String[locs.size()] ) );
    }

    public static MgrBeanB getMgrBeanB() {
    if ( ac == null ) {
    initApplicationContext();
    }

    return (MgrBeanB) ac.getBean( "MgrBeanB" );
    }

    here the applicationContext-DataAccess.xml is the same as the one mentioned above.
    The applicationcontext-OtherMgrs.xml defines the MgrBeanB, and looks like this


    <bean id="MgrBeanB" class="org.springframework.transaction.interceptor .TransactionProxyFactoryBean">
    <property name="transactionManager">
    <ref bean="transactionManager"/>
    </property>
    <property name="target">
    <ref local="MgrBeanBTargetBean"/>
    </property>
    <property name="transactionAttributes">
    <props>
    <prop key="*">PROPAGATION_REQUIRED</prop>
    </props>
    </property>
    </bean>

    <bean id="MgrBeanBTargetBean" class="com.test.MgrBeanB">
    <property name="appResource">
    <ref bean="appResourceBean"/>
    </property>
    <property name="basicInfoDao">
    <ref local="basicInfoDaoBean"/>
    </property>
    </bean>
    ....

  4. #4
    Join Date
    Aug 2004
    Location
    Montréal, Canada
    Posts
    845

    Default

    The issue i'm facing currently is , if there is an exception raised in performActionTwo() i expect the whole operation being rolled back, but the actually what happens is the callMgrBeanInJarToPerformActionInDB(); is committed irrespective of what happens in MgrbeanA.
    your methods are not wrapped in the same transaction because you are using different Spring Contexts / DataSource / Tranaction Managers...

    Is there any reason why you are using two ApplicationContexts?
    If possible, you may remove your singleton MyBeanProvider, and configure all your beans using IoC. Using only one singleton (Spring) will, for sure, improve your application design / maintenability / ...

    Is my approach correct, should i be,
    1. not define datasources seperate if i want to propogate the transaction
    2. merge my application contexts into one
    3. make the application contexts hierarchial
    1. Yes
    2. It depends on your project
    3. same as 2.

    HTH
    Omar Irbouh

    Spring Modules Team
    http://irbouh.blogspot.com/

  5. #5
    Join Date
    Oct 2004
    Posts
    9

    Default

    Hi irbouho

    Thanks.

    the reason i had two application contexts was to ensure that the beans defined in the second application context are retrieved from one place ie the MyBeanProvider, and refer to the bean instances in code rather than in the bean config.

    well looks like i'm better off with one application context and using spring to wire all the necessary dependencies for now..

    one question though .. how to i access this applicationcontext created thru the contextloaderservlet as defined in web.xml, throughout my application, such as an helper class some where down the line, to get beans from it(programmatically)..

  6. #6
    Join Date
    Aug 2004
    Location
    Montréal, Canada
    Posts
    845

    Default

    one question though .. how to i access this applicationcontext created thru the contextloaderservlet as defined in web.xml, throughout my application, such as an helper class some where down the line, to get beans from it(programmatically)..
    One small hack I used before is to make your MyBeanProvider Singleton imlpements BeanFactoryAware / ApplicationContextAware and configure it inside your applicationContext.xml.
    MyBeanProvider will then delegate bean creation to BeanFactory / ApplicationContext.

    HTH
    Omar Irbouh

    Spring Modules Team
    http://irbouh.blogspot.com/

  7. #7
    Join Date
    Oct 2004
    Posts
    9

    Default

    let's say in the following scenario, i have a controller that delegates methods to a MgrBean (which is created thru the bean defintion of the controller) and the Mgr needs to call the Singleton, how do i access the singleton(if it is defined in applicationcontect.xml and is ApplicationContextAware), should i make the singleton a member of the Mgr Bean and define it as part of the Mgr Bean definition so spring instantiates it or can i access a getInstance static method on the Class of the Singleton ?

  8. #8
    Join Date
    Aug 2004
    Location
    Montréal, Canada
    Posts
    845

    Default

    newToSpring,

    As I said, my code was a hack, and it should be avoided whenever you can. Now, what I am trying to explain is how to minimize the refactoring needed to make your existing code integrate with Spring IoC.

    1. should i make the singleton a member of the Mgr Bean and define it as part of the Mgr Bean definition
    This seems to be an excellent choice. However, If objects created by your singleton are POJOs, you have better to configure them inside your application.xml and add respective properties to your MgrBean.

    2. can i access a getInstance static method on the Class of the Singleton
    You can configure MyBeanprovider inside your applicationContext using factory-method. Spring has build-in support for such case:
    Code:
    <bean id="myBean"
          class="MyBeanProvider"
          factory-method="getInstance"/>
    You can also specify if Spring should manage this been as a prototype or singleton.
    Beans that are managed by Spring need to declare a reference to myBean, while classes that do not have access to your application context can use MyBeanProvider.getInstance().

    Since you are loading the applicationContext using ContextLoaderListener/ ContextLoaderServlet, there should be no problem with a class calling MyBeanProvider.getInstance() before the ApplicationContext has been injected by Spring inside it. You should however pay attention to using MyBeanprovide outside of a web application.

    HTH
    Omar Irbouh

    Spring Modules Team
    http://irbouh.blogspot.com/

  9. #9
    Join Date
    Oct 2004
    Posts
    9

    Default

    Thanks..that seems to work for me..

  10. #10
    Join Date
    Oct 2004
    Posts
    1

    Default Could you please post the final working code please?

    I will realy appreciate it if you could post the final working code from your application.
    Thanks

Similar Threads

  1. Runtime Quartz jobs and ApplicationContext
    By vmarcinko in forum Container
    Replies: 7
    Last Post: Feb 5th, 2008, 11:21 PM
  2. problems loading applicationcontext
    By andrea_z in forum Web
    Replies: 6
    Last Post: Feb 8th, 2006, 08:25 AM
  3. Replies: 2
    Last Post: Oct 13th, 2005, 09:58 AM
  4. Replies: 4
    Last Post: Jun 8th, 2005, 06:22 AM
  5. Obtaining ApplicationContext for web and batch apps
    By Thomas Vaught in forum Container
    Replies: 10
    Last Post: May 23rd, 2005, 07:09 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •