Announcement

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

  • Isomorphic
    replied
    Seems like you could change your handleDSRequest() overrides to throw an Exception if the status is less than 0. Then, you could add your transaction commit/rollback logic to an override of processRequest(), invoking super.processRequest() in a try/catch block and performing a rollback if an Exception is caught.

    Would that work for you?

    Leave a comment:


  • ksenia_korenkova
    replied
    Hi Isomorphic,
    Any updates regarding my question?
    I created a separate post but it was deleted due to duplicate reason.
    I could not find any similar question.
    If there is already an answer please provide it here?

    Leave a comment:


  • ksenia_korenkova
    replied
    Hi Isomorphic,
    We are now almost done with this migration from using Isomorhic transaction to use spring transaction.
    But currently we faced with the issue that we can't use one Spring Transaction when the queue request was send through the REST.
    So we have our own overridden RestHandler which extends com.isomorphic.servlet.RESTHandler and there is only method which we could use to override and start spring transaction and decide if we want to commit or rollback:
    public DSResponse handleDSRequest(DSRequest dsRequest, RPCManager rpcManager, RequestContext context) throws Exception{
    TransactionStatus status = txManager.getTransaction(def);
    try {
    DSResponse response = getResponse(dsRequest, rpcManager, context);
    if (response.getStatus() >= 0) {
    txManager.commit(status);
    } else {
    txManager.rollback(status);
    }
    return response;
    }
    But this will work for every request in the queue, so it means every time the transaction will be started for every request from the queue.
    But this is not what we want because it contradict to the original behavior. (1 queue - 1 transaction)
    There is one more method:
    public void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    But this one doesn't contain any useful information to decide if we need to commit or not (at least rpcManager parameter will be useful).
    Currently we use SmartClient Version: v10.0p_2018-06-25/PowerEdition Deployment (built 2018-06-25)
    We found out that in java doc for 12 version you introduce this new method:
    public void processRestTransaction(RPCManager rpcManager, RequestContext context) throws java.lang.Exception https://www.smartclient.com/smartgwt...STHandler.html

    It is not possible for us now to update from 10 to 12 version but we need to use this feature with using Spring Transaction.
    Could you provide us the way how we can do it in Rest Handler for 10 version?

    Best Regards, Ksenia

    Leave a comment:


  • Isomorphic
    replied
    On your first question: requests that come from a client are always queues, even if they only contain one DSRequest (a queue with a single request in it is a very common case).

    You should be able to use Spring's getWebApplicationContext() method, like the example code does, but you can call the SmartClient utility SpringApplicationContextProvider.getApplicationContext() if you prefer. That does require you to register the bean, as you say.

    The error you now have is happening because SmartClient needs a way to lookup the JNDI connection being used by Spring, and this needs to be configured. This does not appear to be documented, so apologies for that, we will correct it. You need to register a bean like this in your applicationContext.xml files:
    Code:
      <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <!-- Set this to the JNDI name Spring is using -->
        <property name="jndiName" value="isomorphic/jdbc/defaultDatabase"/>
      </bean>
    and then add a line like this to your server.properties:
    Code:
    # Set this property to match the "id" of the JndiObjectFactoryBean registered in Spring
    sql.spring.jdbcDataSourceBean: dataSource

    Leave a comment:


  • ssequeira
    replied
    Ping

    Leave a comment:


  • ssequeira
    replied
    Hello.
    A couple of questions about this: does it work only for RPCQueue? Does it also work for single DSRequests?
    Related to the code you posted, I have tried this as well, but there is something else which seems to be missing.
    I was first getting an error related to the framework not being able to get the Spring Application Context.
    After researching a bit I found that I potentially need to define a bean

    Code:
         <bean id="springApplicationContextProvider"
     class="com.isomorphic.spring.SpringApplicationContextProvider" />
    After I have done it, that error is gone, but now I am getting
    "java.lang.Exception: No value for property sql.spring.jdbcDataSourceBean found in server.properties"

    I could not find anywhere on the spring integration guide (nor by following the links on the spring integration guide page) which could help me figure out the full configuration needed.
    Can you please point me in the right direction?
    Last edited by ssequeira; 3 Mar 2017, 03:08.

    Leave a comment:


  • Isomorphic
    replied
    We will correct that obvious error in the documentation, and also review it to see how we can make things clearer, but to solve your immediate problem, here is how we set things up for the internal automated tests of this feature:

    IDACall replacement
    Code:
    public class SpringTransactionIDACall extends IDACall {
    
        @Override
        public void processRPCTransaction(RPCManager rpc, RequestContext context) throws Exception {
            ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
            QueueServiceBean queueBean = (QueueServiceBean)ac.getBean("queueServiceBean");
            queueBean.processQueue(rpc);
       }
    }
    Transactional Spring bean
    Code:
    @Transactional(isolation=Isolation.READ_COMMITTED, propagation=Propagation.REQUIRED)
    public class QueueServiceBean {
     
        public void processQueue(RPCManager rpc) throws Exception {
            rpc.processRPCTransaction();
        }
    }
    So, the SpringTransactionIDACall.processRPCTransaction() override will be invoked by the normal SmartGWT client-server flow. It creates the Spring bean and calls its processQueue() method, which causes Spring to start a transaction, and the processQueue() method then calls back into normal SmartGWT processing; now, the SmartGWT queue processing is wrapped inside that transactional method. As long as the DSRequests are for DataSources or OperationBindings that have been marked useSpringTransaction="true", and SmartGWT's normal transaction processing is in force (see autoJoinTransactions), all DSRequests in the queue will use the Spring-managed transaction, and Spring will deal with committing or rolling back the transaction when the queue is complete, and thus the QueueServiceBean.processQueue() method ends.

    Note, the client-side automated tests in question call RPCManager.setActionURL() to redirect DSRequest calls to the URL where this special SpringTransactionIDACall is listening, but if you want this approach globally, just map the normal IDACall address to that servlet in your web.xml file.

    Regards,
    Isomorphic Software Support

    Leave a comment:


  • ssequeira
    replied
    I am using smartgwt power 5.0 18.01.2017
    I read the http://www.smartclient.com/smartgwte...tegration.html because I would like smartGWT to participate in a Spring managed transaction.
    I cannot make it to work.
    This is what I have so far:

    Code:
    @Component
    public class TransactionSupportBeanImpl extends JdbcDaoSupport implements TransactionSupportBean {
    
        @Autowired
        private JdbcTemplate jdbcTemplate;
    
        @Override
        @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
        public void startTx() {
            jdbcTemplate.queryForInt("select 1 from dual");
        }
    
    }
    
    @Component
    public class IDACall<RT> extends com.isomorphic.servlet.IDACall {
    
    @Autowired
        private TransactionSupportBean transactionSupportBean;
    
        @Override
        public void processRPCTransaction(RPCManager arg0, RequestContext arg1) throws Exception {
            transactionSupportBean.startTx();
            super.processRPCTransaction(arg0, arg1);
        }
    
    }
    This does not work.
    I tried to follow the documentation, but it isn't clear what to do.
    The code which is there is also wrong. You have a method declaration inside a method declaration...
    Code:
     @Transactional(isolation=Isolation.READ_COMMITTED, propagation=Propagation.REQUIRED)
         public class MyServiceBean {
      
             public void processQueue(HttpServletRequest req, HttpServletResponse resp) 
             throws Exception 
             {
                 // invoke Smart GWT server standard request processing
                 public void processQueue(RPCManager rpc) throws Exception {
                     rpc.processRPCTransaction();
                 }
             }
         }

    Leave a comment:


  • Isomorphic
    replied
    As it happens, this was sponsored and checkins for the feature have just started. Within a few days you'll see new docs for it in 5.0d builds.

    Leave a comment:


  • pwcolinx
    replied
    SQL Datasource and Spring transaction manager

    Was this feature ever implemented?

    Leave a comment:


  • Isomorphic
    replied
    As stated above - it could be implemented, it's not currently planned, but it would be a valid Feature Sponsorship.

    Leave a comment:


  • mpretorian
    replied
    Is this feature in the meantime planned to be implemented or already implemented?

    Leave a comment:


  • mpretorian
    replied
    There is a class in spring library called DataSourceUtils that makes all the work.
    Couldn’t be used that class to obtain a connection from a datasource taken from JNDI in SmartWGT server framework?
    Have a look to the implementation of this method: org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSource).
    It returns a managed connection if exists or falls back to the connection from the jndi datasource.
    So it doesn't break the existing functionality but adds a lot of possibilities to how a datasource can be implemented as a combination between SQLDatasource and custom access to database.

    Leave a comment:


  • Isomorphic
    replied
    It could be implemented, it's not currently planned, but it would be a valid Feature Sponsorship.

    Leave a comment:


  • mpretorian
    replied
    Do you think that would be possible in the future to configure an SQL Datasource with an external transaction manager? Is it already planned such a feature?

    Leave a comment:

Working...
X