Announcement

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

    #16
    As you figured out, the queued requests do not contain the delete, so an automatic transaction is not initiated with the default transaction policy, as per docs.

    You can switch the policy to ALL just for this HttpRequest or system-wide. In this case, yes, setRPCManager() is required to make the manually initiated DSRequest join the transaction. This is always required for a manually initiated DSRequest to join an auto-transaction.

    You would not normally use the DSTransaction APIs if you are already in an HttpRequest lifecycle where auto-transactions are in use; this API principally exists for standalone usage (outside of a servlet engine). However, for such usage, yes, the APIs that the docs show as required are required. We might simplify this in the future however.

    Comment


      #17
      Hi Isomorphic,

      my question about RPCManager is regarding the new API in 5.1 using DSTransaction.
      So if I understand correctly, the following is necessary in 5.1 for joining a transaction:

      Either the policy = ALL or for manual DSRequests in the server-side:
      1) request.setTransaction(transaction)
      2) transaction.registerRequest(request)
      3) request.setRPCManager(rpcManager)

      If I understand your post correctly, setRPCManager() is required for the manually initiated DSRequest to join the transaction although request.setTransaction(transaction) is set ?

      Comment


        #18
        No. Please start first by reading the docs - this thread seems to have gotten you confused on some points which are quite clear in the docs.

        For an auto-transaction, setRPCManager() is all you need, and the docs are very clear on this. Your use case doesn't require looking at any of these other APIs. There is no reason you'd be calling setTransaction or registerRequest.

        If you care to revisit those other APIs when the relevant use case comes up, again there is a usage sample in the Standalone Transactions overview, which shows what APIs to call.

        Comment


          #19
          But there is no auto-transaction to join! as we saw in this thread with the default setting (ANY_CHANGE) and two server-side DSRequests (http://forums.smartclient.com/forum/...4#post233714): "you can see that the ANY_CHANGE-setting only applies when there are change requests in the *client-sent*-queue.This is clear because the framework can't know your DMI method beforehand."
          So in my case, since I am not having any client-sent queue, I need either ALL or ANY_CHANGE, and if I have ANY_CHANGE I have to call setTransaction() and registerRequest(). Or what I am understanding wrong?
          Why do you claim that I only need setRPCManager()? That is what is not working in the first place (if I have ANY_CHANGE as setting). If I have ANY_CHANGE as as setting, I have to manually add the server-side requests to the transaction using setTransaction and registerRequest, or ?

          Comment


            #20
            Again:

            You can switch the policy to ALL just for this HttpRequest ...
            .. so do that, and then setRPCManager() works.

            Blama covered this too (post 9).

            Comment


              #21
              Yes, setting the policy to ALL for this HttpRequest would work. This is understood.
              But as an alternative I thought to use setTransaction() and registerRequest() for the DMIMethod needed, when upgrading to 5.1, as pointed out by blama. But you say this is not a use case for using these methods? This is the part that I don't understand: why there is no reason for calling setTransaction or registerRequest? Or why is it better to set the policy to ALL for this HttpRequest only and not to use setTransaction and registerRequest for the DsRequest

              Comment


                #22
                Because you can handle this use case without those APIs, by using APIs that you will definitely need to use again elsewhere. This reduces the total number of concepts that need to be understood to follow your code.

                Comment


                  #23
                  Note we've just updated the sample code for Standalone transaction usage. The calls to registerRequest() were redundant with the calls to setDSTransaction(), only setDSTransaction() is really required.

                  Comment


                    #24
                    Hi Isomorphic,
                    Originally posted by Isomorphic View Post
                    Note we've just updated the sample code for Standalone transaction usage. The calls to registerRequest() were redundant with the calls to setDSTransaction(), only setDSTransaction() is really required.
                    thanks, I already thought so.
                    Could you also say what you think about the improvement suggestion from #9, which would edulid's original use case without any extra code?

                    Best regards
                    Blama

                    Comment


                      #25
                      Consider how such a rule behaves if there is a queued fetch, DMI delete after the fetch, and second queued fetch. The transaction boundary falls after the first fetch, meaning that something could go wrong with the delete since the fetched data might have been stale due to concurrent data change. So introducing this rule doesn't actually provide any kind of automatic safety for operations initiated by DMIs; only using the "ALL" setting or reasoning correctly about your transactions can do that.

                      We don't want to introduce a new behavior that is more difficult to explain and think through, yet still doesn't really offer the safety of the existing ALL setting.

                      Comment


                        #26
                        Hi Isomorphic,

                        OK, thank you. I agree that it would make understanding what happens even more difficult.

                        So with respect to posts #19-#21 in the other thread, the one solution is to use what you mentioned in #21 over there (my pseudo code here in #11).
                        But it is also possible (and most likely easier to maintain and understand) to define it declaratively in .ds.xml, like you mentioned in the other thread:
                        Originally posted by Isomorphic View Post
                        If you make the change to ALL and discover that it has an adverse performance impact on your plain fetch requests, you may wish to consider using a transaction policy of FROM_FIRST_CHANGE. Note, as discussed in the autoJoinTransactions doc we linked you to earlier, you can set the server.properties property "autoJoinTransactions" to a transaction policy as well as true/false, so if you want to do this, you don't have to programmatically call setTransactionPolicy() on every RPCManager instance - you can still apply this change declaratively.
                        So best for performance and data integrity is to leave the default transaction policy (ANY_CHANGE) and set autoJoinTransactions=true on the operationBinding, correct?

                        These two in combination mean that whenever a clientside request comes in for on of those operationBindings, the transactionPolicy for this RPCRequest is ALL, correct?
                        The .ds.xml autoJoinTransactions-transaction attribute supports the same values like the server.properties, setting, doesn't it (true/ALL, false/NONE and the other possible for RPCManager.setTransactionPolicy())?

                        If so, I'm going to change to that configuration from my current server.properties autoJoinTransactions: true

                        Thank you & Best regards
                        Blama

                        Comment


                          #27
                          It's not clear what we can add to the docs here...

                          As documented, the autoJoinTransactions attribute, when set on the <DataSource> or <operationBinding> elements, is a boolean property. So no, it doesn't support non-boolean values such as "ALL". It only controls that particular DataSource or operationBinding, so those settings wouldn't make sense.

                          As far as usage advice, no single setting is the "ideal" one for all circumstances (that's why there are settings). From the point of view that you seem to be spending a lot of time on this with no benefit we can foresee, we would say: use the "ALL" setting so you always default to transactions and never have to think about it. Then, if you notice an all-fetch queue is slow (which would be unusual), and you then isolate the performance problem to the use of transactions, consider another setting just for that queue.

                          Comment


                            #28
                            Hi Isomorphic,

                            Originally posted by Isomorphic View Post
                            As far as usage advice, no single setting is the "ideal" one for all circumstances (that's why there are settings). From the point of view that you seem to be spending a lot of time on this with no benefit we can foresee, we would say: use the "ALL" setting so you always default to transactions and never have to think about it. Then, if you notice an all-fetch queue is slow (which would be unusual), and you then isolate the performance problem to the use of transactions, consider another setting just for that queue.
                            OK, I'll do so. It is set to "ALL" here now and I don't have performance problems with my request-duration. For me, this was only about understanding the way the framework works here.

                            Best regards
                            Blama

                            Comment


                              #29
                              Hi Isomorphic,

                              Originally posted by Isomorphic View Post
                              Note we've just updated the sample code for Standalone transaction usage. The calls to registerRequest() were redundant with the calls to setDSTransaction(), only setDSTransaction() is really required.
                              the sample still mentions registerRequest() in the source code comments.
                              I think a sample with manually calling DSRequest.execute(), but still using DSTransaction would be helpful, so that one knows how to clean up in this case (dst.complete()? dst.freeAllResources()?).
                              For me, this will be the way I'll be using the feature, as the 2nd request's values are dependent on the 1st request's result.

                              Best regards
                              Blama

                              Comment


                                #30
                                Nice spot, thanks Blama. We've now updated the documentation and removed any references to the registerRequest() method and added another short sample showing how to manually manage request execution and clean up when not calling dsTransaction.processQueue().

                                To spare you from having to read the documentation we can tell you that you simply need to call dsTransaction.complete() just like for the processQueue() scenario. This method will ensure that any database commits/rollbacks take place and that any resources used are freed up.

                                Comment

                                Working...
                                X