Results 1 to 6 of 6

Thread: Spring declaration transaction issue

  1. #1
    Join Date
    May 2006
    Posts
    3

    Default Spring declaration transaction issue

    public void methodA()
    {
    for(int i=0; i<10000; i++)
    {
    methodB();
    }

    }

    public void methodB()
    {
    // do something...
    }

    declaration transaction in application-service.xml for these two methods as follows.

    <property name="transactionAttributes">
    <props>
    <prop key="methodA">PROPAGATION_NOT_SUPPORTED</prop>
    <prop key="methodB">PROPAGATION_REQUIRES_NEW</prop>
    </props>
    </property>

    We find the methodB() is running out of transaction control, that is, methodB will never rollback while some exceptions raised here.

    if you know the reason, pls give me some advice. Thanks.

  2. #2
    Join Date
    Aug 2004
    Posts
    2,715

    Default

    It's the usual delegating proxy effect. If you invoke a method on the same instance, that call does not get proxied.
    If you would do this on an EJB it would not work either, as you would need to first get a handle on the instance and invoke the method on that handle.

    There are different solutions:
    - You could use AspectJ, where also invocations on "this" can be intercepted
    - You could inject the proxy as a "This" property, invoking the method on it
    - You could refactor the methods into different classes and use the current approach

    Regards,
    Andreas

  3. #3
    Join Date
    May 2006
    Posts
    3

    Default

    Hi Andreas,

    Thank you very much. But I am still puzzled about the option 2 of your three solutions. Could you give me some details explanation for the second option?

    Thanks
    Sam

  4. #4
    Join Date
    Aug 2004
    Posts
    2,715

    Default

    Here is a simple example:

    The context:
    Code:
      <bean id="foo" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="targetName" value="fooTarget"/>
        <property name="interceptorNames">
          <list>
            <value>interceptor</value>
          </list>
        </property>
      </bean>
    
      <bean id="interceptor" class="org.springframework.aop.interceptor.SimpleTraceInterceptor">
      </bean>
    
      <bean id="fooTarget" class="test.spring.Foo">
        <property name="this" ref="foo"/>
      </bean>
    ...and the code:
    Code:
    public class Foo {
    
      private Foo thisInstance = this;
      
      public Foo() {}
    
      public Foo getThis() {
        return this.thisInstance;
      }
    
      public void setThis(Foo pThisInstance) {
        this.thisInstance = pThisInstance;
      }
    
      public void op1() {
        System.out.println("op1");
      }
      
      public void op2() {
        System.out.println("op2 calling op1");
        getThis().op1();
      }
    }
    Note the usage of getThis().op1() instead of just writing this.op1(). By initializing "thisInstance" with "this", the code will continue to work without proxying.

    Regards,
    Andreas

  5. #5
    Join Date
    Aug 2007
    Posts
    1

    Unhappy Using @Transactional annotations

    I'm having the same problem i.e. same class method called from another but not starting new transaction. But I'm using the @Transactional annotations, and so can't inject thisInstance. Any idea how I get around this? (no pun intended).

    Thanks,

    Hugh

  6. #6
    Join Date
    Aug 2004
    Posts
    2,715

    Default

    I guess the only options are to either redesign your code or to use AspectJ to overcome this.

    Regards,
    Andreas

Posting Permissions

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