Announcement

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

    Recommended approach for complex DB actions

    What is the recommended approach for executing DB actions that include more than one fetch/update/remove operations?

    As an example, I want to add a record to a table. But, in order for that, I have to fetch another tables for getting the necessary ids, remove records from another tables, etc.

    Until now, I did that in a client-based manner, using callbacks when the individual operations were executed. So the "big" operation was done sending small fetch/update/insert operations to the server.
    But this was sometimes complicated, so I started investigating how to move that to a server-based manner.

    I defined a custom operation:
    Code:
    <operationBinding operationType="custom"
    			operationId="addBigRecord">
    			<serverObject
    				className="server.dmi.OperationDMIHandler"
    				methodName="addBigRecord" />
    		</operationBinding>
    which is the "big" operation. There, in "addBigRecord", I do all necessary steps for achieving this (using server-based DSRequests). I like this approach, since I don't have to send data to the client until the big operation is completed.
    Is this a recommended approach or would you rather recommend the client-based approach?

    Using smartgwt 4.1 power.

    #2
    If it avoids downloading a bunch of data to the client that the client can't use, then yes, doing it on the server makes sense.

    You can use DSResponse.addRelatedUpdates to update multiple affected DataSources if needed.

    You can also, in some cases, declare the entire multi-step operation without writing Java code as such - see operationBinding.criteria/values.

    In 5.1, a new feature dsRequest.fieldValueExpressions makes it possible to drive some orchestrated multi-step server operations entirely with client-side logic.

    Comment


      #3
      Originally posted by Isomorphic View Post
      If it avoids downloading a bunch of data to the client that the client can't use, then yes, doing it on the server makes sense.
      The amount of data downloaded is minimal, but it consists of different steps. On this case, would you still recommend doing this at the server?

      You can use DSResponse.addRelatedUpdates to update multiple affected DataSources if needed.
      Maybe I misunderstand something about addRelatedUpdates(), but isn't this method used to SIMULATE an update, or a remove operation, for example?
      In the docs: "Causes client-side components to react as though the provided DSResponse had just successfully completed.",... so how would you use this API for executing REAL further updates ?

      Comment


        #4
        Hi edulid,

        definitely go for the server-way. An additional advantage is that you can have all your changes in a single transaction - succeeding or failing in an atomic way.

        I'd think (not sure) that the correct operationType is not custom but add (in case of your addBigRecord) or whatever makes sense logically (see the "Non-Crud Operations"-chapter in the Quick Start Guide).

        Regarding relatedUpdates: You can also use it to piggyback real DSResponses to the server, but make sure to use a correct operationType.
        Example: A DB-view (with own .ds.xml) depends on a table (another .ds.xml).
        You update a field in the table, have DMI there, execute the update, issue a fetch to the view's DS manually and add it to the 1st request's result.
        Then you got this change's results with just 1 round-trip. But make sure to fake the fetch's OperationType to update before returning it to the client, in order to enable the clientside framework to include it in its cache.

        Best regards,
        Blama

        Comment


          #5
          Originally posted by Blama View Post

          Regarding relatedUpdates: You can also use it to piggyback real DSResponses to the server, but make sure to use a correct operationType.
          Example: A DB-view (with own .ds.xml) depends on a table (another .ds.xml).
          You update a field in the table, have DMI there, execute the update, issue a fetch to the view's DS manually and add it to the 1st request's result.
          Then you got this change's results with just 1 round-trip. But make sure to fake the fetch's OperationType to update before returning it to the client, in order to enable the clientside framework to include it in its cache.
          Hi Blama,
          thank you for your answer.
          I think we are talking about the same :-) Please take a look at http://forums.smartclient.com/showthread.php?t=31348 : I do exactly what you are describing in your answer: the view is "testDatasource" and the update-datasource is "vertraege". So when I update "vertraege", I issue a fetch on the view's DS manually and add it to the 1st request's result, exactly as you describe (refer to StatusDMIHandler.java).

          But here we are not updating multiple affected datasources, but we are using a DMIHandler to simulate a second update (the update on the view). What I understood from Isomorphic's response ("You can use DSResponse.addRelatedUpdates to update multiple affected DataSources if needed. ") is that several *real* updates may be propagated using relatedUpdates, but here we are only executing the "real" one and "simulating" another one. That's why I asked for clarification.

          Of course, we could issue a *real* second update in the DMIHandler. But that could be done using a simple DMIHandler, without adding the second update to the relatedUpdates(). Of course, in order to inform the client about the changes, we could use relatedUpdates()... but in order to execute the *real* second update, we don't need relatedUpdates()... or am I understanding something wrong?
          Last edited by edulid; 28 Sep 2014, 22:46.

          Comment


            #6
            Hi edulid,

            I think you are right.

            Aggregation: If you do any other server side change besides the base-create/update/delete you want to inform the client about, you must use addRelatedUpdates().
            If the client does not need to know about the additional changes, using addRelatedUpdates() is wasting bandwidth.
            If the piggyback data comes from a fetch, change the OperationType of the DSResponse before adding it with addRelatedUpdates().

            I'll look at your other post if I find the time. It seems to be long :)

            Best regards,
            Blama

            Comment


              #7
              Originally posted by edulid View Post
              The amount of data downloaded is minimal, but it consists of different steps. On this case, would you still recommend doing this at the server?
              Because doing it on the server avoids multiple round-trips from client to server, we would generally recommend doing this server-side, yes.


              Maybe I misunderstand something about addRelatedUpdates(), but isn't this method used to SIMULATE an update, or a remove operation, for example?
              In the docs: "Causes client-side components to react as though the provided DSResponse had just successfully completed.",... so how would you use this API for executing REAL further updates ?
              Use addRelatedUpdates() any time you need to inform the browser-side system of changes that have happened where SmartGWT did not actually execute a DSRequest.

              An example is a cascading delete caused by SQL declarations. SmartGWT code doesn't actually execute a series of "remove" operations, but database rows have been removed, and you can inform the client-side system of the changes via addRelatedUpdates().

              Comment


                #8
                Ok, thank you for the information.

                Comment

                Working...
                X