Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Multiple forms : Transaction Management :RPCManager

    I am developing an application using Smart GWT, Spring & JPA. On the user interface, I have multiple forms which are submitted as single request using RPCManager as shown below:
    RPCManager.startQueue();
    dynamicForm1.saveData();
    dynamicForm2.saveData();
    dynamicForm3.saveData();
    RPCManager.sendQueue();

    Each dynamic form is associated with the SmartGWT datasource. Sample of the datasource is as follows:
    <DataSource
    beanClassName="com.dialog.vba.server.model.TaxonLifestyle"
    ID="TaxonLifestyle_DS"
    dataSourceVersion="1"
    serverConstructor="com.isomorphic.jpa.JPADataSource"
    serverType="hibernate"
    >
    <fields>
    <field title="Active Time of the Day" name="activeTimeOfDayCde" type="text"></field>
    <field title="Creation Tsp" name="creationTsp" type="datetime"></field>
    <field title="Taxon Diet" name="dietCde" type="text"></field>
    <field title="Hollow Dependence" name="hollowDependenceCde" type="text"></field>
    <field title="Modified Tsp" name="modifiedTsp" type="datetime"></field>
    <field title="Taxon" name="taxon" javaClass="com.dialog.vba.server.model.Taxon" canEdit="true" type="Taxon_DS" multiple="false" ignore="true"></field>
    <field title="Taxon Cde" hidden="true" primaryKey="true" name="taxonCde" type="text"></field>
    </fields>

    <serverObject lookupStyle="spring" bean="taxonDescriptionBo" />

    <operationBindings>
    <binding operationType="fetch" serverMethod="fetchLifestyle" />
    <binding operationType="update" serverMethod="updateLifestyle" />
    <binding operationType="add" serverMethod="updateLifestyle" />
    </operationBindings>


    </DataSource>

    As it can be seen in DS, update methods in the bo (service class) will be called.
    Hence, in my case, for each dynamic form, an update method in the bo will be called.
    The issue I am getting is as follows:
    In bo, transaction are managed at each method. Hence, if a single method (say dynamicform3 update method) has exception only that transaction is rolled-back while other bo methods are committed. I do not want this to happen. If any method has an exception, entire transaction should roll-back. i.e. data from all forms should save or no data should be saved to database.
    I cannot use ValuesManager as each form has different datasource. In the project, each datasource is mapped to POJO and eventually to a table in the oracle database.
    Could you please suggest how it can be done using RPCManager in the above scenario?
    Last edited by thisisgk; 28 Oct 2010, 16:21.

    #2
    Rollback if any one operation fails is currently automatic for the SQLDataSource and HibernateDataSource, but the JPADataSource does not yet have this feature.

    A few options:

    1) switch to HibernateDataSource, at least temporarily until the feature is added

    2) sponsor transaction support for JPA

    3) write a custom DataSource and include transaction support

    Comment


      #3
      Our company is in process of purchasing licenced copy of SmartGWT and hence would like to know how soon will the roll-back operation is expected to be available in JPADataSource?

      Using HibernateDatasource would require large amount of code refactoring. Hence, I am currently not looking into it.

      I tried creating a custom Datasource. But a new instance of same was always created and each transaction was executed independent of each other. My custom datasource is as follows:
      Code:
       package com.dialog.vba.server.bo.impl;
      
      import javax.persistence.EntityManager;
      import javax.persistence.EntityManagerFactory;
      import javax.servlet.http.HttpServletRequest;
      import org.apache.log4j.Logger;
      import org.springframework.orm.jpa.JpaTransactionManager;
      import org.springframework.transaction.TransactionDefinition;
      import org.springframework.transaction.TransactionStatus;
      import org.springframework.transaction.annotation.Transactional;
      import org.springframework.transaction.support.DefaultTransactionDefinition;
      import org.springframework.web.context.support.WebApplicationContextUtils;
      import com.dialog.vba.server.BusinessThread;
      import com.isomorphic.datasource.DSRequest;
      import com.isomorphic.datasource.DSResponse;
      
       
      @Transactional
      
      public class TransactionManager extends com.isomorphic.jpa.JPADataSource {
      
      
      
      private EntityManager entityManager = null;
      
      private Logger logger = Logger.getLogger(TransactionManager.class);
      
      private static int i=0;
      
      
      
      public TransactionManager () {
      
      System.out.println(" i am created !!! ");
      
      logger.debug(" i am created.  i = " + i++);
      
      
      
      }
      
      
      
      @Override
      
      public DSResponse execute(DSRequest req) throws Exception {
      
      DSResponse response = null;
      
      try {
      
      logger.debug(" i = " + i++);
      
                
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().begin(); 
      
      response = super.execute(req);
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().commit();
      
      }
      
      catch (Exception ex)  {
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().rollback();
      
      throw ex;
      
      }
      
      
      
      return response ;
      
      }
      
      
      
      @Override
      
      public DSResponse executeCustom(DSRequest req) throws Exception {
      
      DSResponse response = null;
      
      try {
      
      logger.debug(" i = " + i++);
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().begin(); 
      
      response =super.executeCustom(req);
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().commit();
      
      }
      
      catch (Exception ex)  {
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().rollback();
      
      throw ex;
      
      }
      
      
      
      return response ;
      
      
      
      }
      
      
      
      @Override
      
      public DSResponse executeFetch(DSRequest req) throws Exception {
      
      DSResponse response = null;
      
      try {
      
      logger.debug(" i = " + i++);
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().begin(); 
      
      response =super.executeFetch(req);
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().commit();
      
      }
      
      catch (Exception ex)  {
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().rollback();
      
      throw ex;
      
      }
      
      
      
      return response ;
      
      }
      
      
      
      @Override
      
      public DSResponse executeAdd(DSRequest req) throws Exception {
      
      DSResponse response = null;
      
      try {
      
      logger.debug(" i = " + i++);
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().begin(); 
      
      response =super.executeAdd(req);
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().commit();
      
      }
      
      catch (Exception ex)  {
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().rollback();
      
      throw ex;
      
      }
      
      
      
      return response ;
      
      }
      
      
      
      @Override
      
      public DSResponse executeRemove(DSRequest req) throws Exception {
      
      DSResponse response = null;
      
      try {
      
      logger.debug(" i = " + i++);
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().begin(); 
      
      response = super.executeRemove(req);
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().commit();
      
      }
      
      catch (Exception ex)  {
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().rollback();
      
      throw ex;
      
      }
      
      
      
      return response ;
      
      }
      
      
      
      @Override
      
      public DSResponse executeUpdate(DSRequest req) throws Exception {
      
      DSResponse response = null;
      
      try {
      
      logger.debug(" i = " + i++);
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().begin(); 
      
      response = super.executeUpdate(req);
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().commit();
      
      }
      
      catch (Exception ex)  {
      
      getEntityManager(req.getHttpServletRequest()).getTransaction().rollback();
      
      throw ex;
      
      }
      
      
      
      return response ;
      
      }
      
      
      
      
      
      
      
      
      
      private EntityManager getEntityManager(HttpServletRequest request) {
      
      if (entityManager == null) {
      
       
      
      org.springframework.web.context.WebApplicationContext context = WebApplicationContextUtils
      
                .getRequiredWebApplicationContext(request.getSession()
      
             .getServletContext());
      
      DefaultTransactionDefinition def = new DefaultTransactionDefinition();
      
      def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
      
      JpaTransactionManager transactionManager = (JpaTransactionManager) context
      
                .getBean("transactionManager");
      
      TransactionStatus status = transactionManager.getTransaction(def);
      
      // transactionManager.
      
      
      
      EntityManagerFactory eMFactoryBean = transactionManager
      
                .getEntityManagerFactory();
      
      entityManager = eMFactoryBean.createEntityManager();
      
      System.out.println("entityManager = " + entityManager);
      
      logger.debug("entityManager = " + entityManager);
      
      }
      
      return entityManager;
      
       
      
      }
      
      
      
      }

      Comment


        #4
        Hello thisisgk,

        We don't have a specific date for JPA transaction support - the way to get a date commitment is to sponsor the feature.

        If you go down the route of a custom DataSource, use the ability to store attributes on the RPCManager or httpServletRequest as a means of using the same Session across multiple DSRequests.

        Comment

        Working...
        X