Thursday, July 14, 2011

why my new transaction is not created spring?

I was inserting a single data from table A to table B and then removing the single instance from table A. I don't want to have a problem if insert happens but the delete does not. So for this action I needed a transactional behavior.

I'm using Spring declaratively and thus using TransactionManager for implementing transactional behavior. I declared my method's propagation as REQUIRES_NEW which mean I absolutely want a new transaction for this method.

In my Service class' process() method I call insertAndDeleteTrxNew().


public void process(){
Record records = stuff();
insertAndDeleteTrxNew(records);
}


insertAndDeleteTrxNew() method inserts from table A to table B and deletes from table A. Spring's log tells me that it did not create a transaction for my method.
What I exactly get is:
Don't need to create transaction for [Service.insertAndDeleteTrxNew()]: This method isn't transactional.

After few time searching I found out the root cause of my problem. Spring build a proxy for my Service class and any transactional behavior will work on this level. If I set process() transactional and call it first I'll implicitly go to the proxy and call proxy's process() method then proxy will call the instance's process() method which's why transactional behavior will work: I first meet with the proxy. My call is handled by the proxy. Why my insertAndDeleteTrxNew() does not work? This is because when I do this call from my process() method, I'm calling this specific instance's method not the proxy's method.

I fixed this problem by extracting this method to another Service. Now, Service X's process() method calls Service Y's insertAndDeleteTrxNew() method which implicitly calls Y's proxy and as you can guess it works.

2 comments:

  1. Hi Sezin,

    The problem the issue am facing is something similar. My project creates this unending log for almost all the beans in the project

    >> Don't need to create transaction for [Service.BEANXxxYyy()]: This method isn't transactional.

    , which seems to consume a lot of time and overfills the logs.

    Could you suggest how can i disable this transactional behavior?

    ReplyDelete
  2. you can set spring logs to info level, so it wont print lots of stuff related to transactions.

    ReplyDelete