0

We recently upgraded our spring version to 4.x from 2.x which started causing some issues with one of our 'threadpooltaskexecutor' implementation.

The implementation was as below:

public class A
{
..............................
..............................

public void create()
{
    this.threadPoolTaskExecutor.execute(new Runnable()
    {
        public void run()
        {
            createABCAsync();
        }
     });
}


public void createABCAsync()
{
    createABC();
}


public void createABC()
{
    .....................................
    ..................................... 
    abcDAO.saveOrUpdate(abc);
    xyzDAO.saveOrUpdate(xyz);
}

................................................... ...................................................
}

The bean definitions for class A has entries like below:

`<bean id="clsIntegrationManager" parent="txProxyTemplate"`>
  .................................................
  .................................................
    <property name="transactionAttributes">
        <props>
              <prop key="create">PROPAGATION_REQUIRED</prop>                   
              <prop key="createABCAsync">PROPAGATION_REQUIRES_NEW</prop>
        </props>
    </property>

After spring upgrade, the above code threw an exception as below:

Exception in thread "threadPoolTaskExecutor-1" org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.

To resolve the above I added an entry like follows in the DAO layer bean definition file:

<bean id ="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
<property name="checkWriteOperations" value="false"/>
</bean>

The above entry resolved the exception, but the asynchronous method execution which starts a separate transaction using REQUIRES_NEW is not doing any database commits. We have a couple of 'saveOrUpdate()' calls inside the createABC() method but nothing gets saved in database.

Can someone please help in understanding what is going wrong above ?

I tried a few different solution approaches, one of which is described here: [Spring TaskExecutor Transaction Lost (Proxy vs. Direct call) but this did not help.

Community
  • 1
  • 1
Anand03
  • 213
  • 2
  • 6
  • 17
  • createABCASync is called from another internal class method createABC hence a new transaction would NOT be started. Are you sure it worked before in spring 2? Strange – Andy Dufresne Dec 15 '14 at 09:31
  • Hi Andy, can you please suggest some way to handle the above scenario? It was working for me with Spring 2.x – Anand03 Dec 15 '14 at 09:44
  • You need to inject the ClassA bean instance in the same class - Self injection and then call classA.createABCAsync() so that a new transaction gets created. Enable spring transaction package logs for verifying that the transaction actually gets started. – Andy Dufresne Dec 15 '14 at 10:24
  • Thanks for your inputs. Can you please help on how I can perform a self injection using setter mechanism? My spring configuration is xml based and not Annotation based – Anand03 Dec 15 '14 at 11:24

0 Answers0