Announcement Announcement Module
Collapse
No announcement yet.
AOP Transactions calling fellow member methods Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • AOP Transactions calling fellow member methods

    I am using Java5 annotations for transaction demarquation on methods.

    How can I obtain the transationactionally aware proxy of the object I am currently executing in, so that the transactional annotations can be
    re-evaluated over a method invocation.

    Since calling a member method (another method in the same "this" instance) results in a direct Java method invocation call and does not cause Spring's transactionally aware proxying to evaluate the situation and do the correct thing.

    Code:
    public class FooImpl {
        @Transactional(propagation = Propagation.REQUIRED)
        public Integer methodOne(int a) {
            int aa = a + 1;
            Integer i = methodTwo(aa);   // Problem, REQUIRES_NEW has no effect
            return i;
        }
        @Transactional(propagation = Propagation.REQUIRES_NEW)
        public Integer methodTwo(int b) {
            resource.doMagic(b);
            return Integer.value(b);
        }
    }

    This problem is well known for EJB related similar situations the following URL describe the well known work around for EJB in this situation:

    http://community.jboss.org/message/525521#525521

    Code:
            FooImpl proxyOfFoo = this.sessionContext.getBusinessObject(FooImpl.class);
            // invoke on that business object with transaction support
            proxyOfFoo.methodOne(b);
    So I am looking for the equivalent of taking "this" and getting "proxyOfFoo" (i.e. the proxy of this, that is transactionally aware).

  • #2
    I suggest the alternative solution: use aspectj instead of aop proxies. Therefore, self invocation would be advised by transactional advice. It would be also possible to advise private methods with transactional advice. However, using aspectj has consequences: you will have to enable javaagent mechanism for load time weaving or use aspectj compiler.

    Comment


    • #3
      Thanks for your reply. This is a shame there is not a built in solution.

      Surely it would be possible for any POJO that has been encapsulated inside a proxy, to have a new interface and method added, so that a POJO method needing this behavior could call a Spring framework provided static method (in another class in spring-whatever.jar). This added method would be able to do whatever was necessary to retrieve the proxy in respect of "this".

      Code:
      MyType myType = org.springframework.made.up.ProxyLookupUtils.getBusinessObject(this, MyType.class);
      For me this kind of usage is the exception not the normal.

      Comment


      • #4
        @dlmiles

        What is your use case? Can you give an example of 'evaluate the situation and do the correct thing'?

        Any method call should still act under the umbrella of the transaction. That is, even though you are calling a private method you are acting under the parent original transaction that spring started on your advised public method, the one that called the private one.

        The transaction will be commited/rollback at the end of execution of your public advised method.


        nicolas.loriente

        Comment


        • #5
          First thanks for your reply.


          Originally posted by nicolas.loriente View Post
          What is your use case? Can you give an example of 'evaluate the situation and do the correct thing'?
          One use case is clearly documented (by me) in this thread. The REQUIRES_NEW is not acted upon, instead of a new transaction being created, it joins the existing one. This is not what is wanted, otherwise I'd have used the default REQUIRES propagation mode.

          The other use case is where you have a method that does not have an @Transactional annotation in the Service implementation, which then goes on to call a fellow method in the same service that does have @Transactional annotation.

          I am aware of what you are saying (in relation to joining the existing transaciton and rollback still working) but this is not that is wanted. The exact intention of the scenario the @Transational describe is what is wanted.


          Originally posted by nicolas.loriente View Post
          The transaction will be commited/rollback at the end of execution of your public advised method.
          Well no.. the rollback will also rollback the joined transaction, because the REQUIRES_NEW had no effect, as a new transaction was not created. Also the implicit commit (and therefore) flush of the inner-nested transaction was not done either (at the point in time the execution returned from the inner method, i.e. returned from the REQUIRES_NEW method).

          Not that I have tested this scenario (since I have never needed it) but this is my understanding of how nested transactions work.


          If you were asking for the use case to better understand the application and context to advise of some alternative stratagy, this isn't really what I want. The EJB case understands the problem and provides a solution, I would guess that I can annotate affected Service implementations for ApplicationContextAware (@Autowired ApplicationContext applicationContext) then lookup the service bean (from inside the service bean implementation method code) so that the resulting getBean() returned the proxied reference (of "this") I am looking for. But this isn't a great solution, since it would hardwire bean names in a place where it is unnecessary, I don't know how efficient the whole approach is compared to just getting the proxy code to edit the POJO implementation it is proxying to add a method and interface. Maybe I can write my own annotation and annotation processor for this job? As I think the annotation processor has access to both the proxy and the proxied (i.e. the POJO). Ideally this whole editing of the POJO in this way could be controlled via XML configuration or an Annotation on class. @AddBusinessObjectLookupInterface
          Last edited by dlmiles; May 17th, 2011, 12:29 PM.

          Comment

          Working...
          X