Search code examples
javacdiwildfly-8transactional

CDI @Transactional with Self Invocation


Environment :

JAVA EE 7

CDI 1.2

WildFly 8.2.0

Code :

I have a JAVA class having following method.

@SessionScoped
@Named("orgBean")
public class OrgBean{

    @Transactional
    public void doSomething(){

        //EM.persist();
        //call private method 
        innerMethod();

    }

    private void innerMethod(){


        EM.persist(); //why is this working ?

    }

}

1)The method doSomething() runs inside a transaction. This method calls another private method innerMethod().

2)The innerMethod() uses EM.persist() call.

Issue/Query :

1)How is EM.persist() working ?

2)I am trying to relate this to Spring framework. Since CDI uses proxies (method invocation OrgBean.doSomething will be through PROXY) and innerMethod is self invocation , how EM.persist() call will work since innerMethod() won't be running inside transaction ?

3)Please correct me if I am wrong.


Solution

  • The code in innerMethod() runs inside the transaction started by the call to doSomething(), and ending when the doSomething() method returns.

    1. transactional proxy's doSomething() method is called
    2. proxy starts a transaction
    3. proxy calls the OrgBean's actual doSomething() method
    4. OrgBeans's doSomething() does whatever it wants, including calling other methods. The proxy doesn't care, and can't even know about it
    5. OrgBeans's doSomething() method returns to proxy's doSomething() method wrapper
    6. transactional proxy commits the transaction.

    In pseudo-code, the proxy basically does the following:

    public void doSomething() {
        startTransaction();
        try {
            orgBean.doSomething();
            commitTransaction();
        }
        catch (RuntimeException e) {
            rollbackTransaction();
            throw e;
        }
    }
    

    It's a bit more complex than that in reality, but you should get the idea.