Announcement Announcement Module
Collapse
No announcement yet.
Spring declaration transaction issue Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    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

    Comment


    • #3
      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

      Comment


      • #4
        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

        Comment


        • #5
          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

          Comment


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

            Regards,
            Andreas

            Comment

            Working...
            X