Question
BNY Mellon
US
Last activity: 7 Apr 2017 6:53 EDT
Posted transaction id DOES NOT match record?
The error message "ERROR: posted transaction id '<md5 hash>' for frame 'pyWorkPage' DOES NOT match record '<md5 hash>' " is as old as PRPC.
Is there a full description of what it means, and what the ramifications are? Does it mean that the posted data is not saved? The log message should be more clear.
This is never accompanied by a stacktrace, but it would be helpful to know what for these what the activity called and pzInsKey/pyID of the case is.
A search for that returns numerous documents about multiple fixes along the way.
This appears in many releases over the years... SA-5031 points to one example in v6.1 sp1 in a grid click... and yet the displayed logs show this occurring in 2014. Was this fixed in v6.2? (We'll probably raise an SR to determine this).
We see this occasionally in production. Today a user clicked a button on a workform (with another form on a separate tab/thread) which called a few Ajax calls, ending with reloadSection(). Is it possible that reloadSection, upon getting an error response, might throw up a new window with a blank "Exception Details" (no message shown). The logs show nothing other than that error message.
The error message "ERROR: posted transaction id '<md5 hash>' for frame 'pyWorkPage' DOES NOT match record '<md5 hash>' " is as old as PRPC.
Is there a full description of what it means, and what the ramifications are? Does it mean that the posted data is not saved? The log message should be more clear.
This is never accompanied by a stacktrace, but it would be helpful to know what for these what the activity called and pzInsKey/pyID of the case is.
A search for that returns numerous documents about multiple fixes along the way.
This appears in many releases over the years... SA-5031 points to one example in v6.1 sp1 in a grid click... and yet the displayed logs show this occurring in 2014. Was this fixed in v6.2? (We'll probably raise an SR to determine this).
We see this occasionally in production. Today a user clicked a button on a workform (with another form on a separate tab/thread) which called a few Ajax calls, ending with reloadSection(). Is it possible that reloadSection, upon getting an error response, might throw up a new window with a blank "Exception Details" (no message shown). The logs show nothing other than that error message.
Also, one way we've avoided this in custom Ajax calls is in not sending the transaction id at all. Where custom code is used, Pega's documentation doesn't stress very much whether to use it. From the help on the pega:url jsp tag:
"Used with a form and a Submit button, the transid
option of the url tag can be useful to maintain synchronization between the servers state and the user's browser state. Ideally, such synchronization works even when a user clicks the Back icon in the browser window. ... When the browser state changes as the result of a user submitting an HTML stream, the pzTransactionID
parameter stores the server state as it corresponds to the current browser stream, tracking where the user has been and where the user is. In some situations, it is important that the browser state and the server state correspond accurately. In situations where the server state data is not relevant, you can omit the transid
option." [emphasis added].
Sure, it can be useful. In which situations?
I searched transid. Here's a question I asked in 2010, never unanswered: https://pdn.pega.com/forums/prpc/java-activities/transid-confusion
Basically, since it takes more work to remember to include <option name="long"> within <pega:url>
When we're in Desktop (JavaScript) API, we have the SafeURL object - which has no mention of primary/transaction/frame at all. So it's just easier to skip this.
***Updated by moderator: Lochan to add Categories***
-
Like (0)
-
Share this page Facebook Twitter LinkedIn Email Copying... Copied!
Pegasystems
US
Hi Jon,
I totally agree the message should be more clear and should be documented in more detail.
However, here is some info about it:
1) Every commit causes the transaction id to change, so if the browser sends a subsequent request to prpc with the old id, that error will result.
2) To debug the situation, use fiddler and look for situations in which a commit occurred but no refreshed screen was sent back to the browser, since such a situation would mean the browser doesn't know the new id. Perhaps it was due to an error preventing the screen from being sent back, or an ajax call provoking the commit such that no refresh-screen was seen by the browser. In fiddler, you can see each transaction id and see where it changed.
3) I do not suggest trying to avoid the error merely be omitting the id, since that will mean you will be sending data for a wrong transaction. All sorts of dangers are possible in that case, such as charging a credit card twice or paying the wrong person.
/Eric
BNY Mellon
US
The situation we saw today did not involve a commit.
If Ajax calls aren't supposed to commit saves, that probably should be documented, no? It goes unmentioned.
https://community.pega.com/sites/default/files/help_v71/procomhelpmain.htm
More of our clients want to do complete processing fully within Ajax. Is there a supported way to accepted a new transid via Ajax?
To your 3rd point -- if Pega wants to encourage submission of primary/frame/transid, there should be an API within SafeURL.
Pegasystems
US
Hi Jon,
If you want to commit a save during an ajax activity, try using the "write now" checkmark on the obj-save instead of using commit.
(However,usually do not use "write now" if what you are updating is the primary work object. In fact, usually, don't even save it, since it is important to rely on the system's own save and commit for this purpose, which will occur when the screen is submitted. This warning is important for avoiding the occasional "flow removed" or "flow not at task" errors that could occur if the system needs to rollback the commit due to an error, which it won't be able to do properlyif a "write now" save or a "immediate" delete or an extra commit has been performed).
/Eric
BNY Mellon
US
If there's a best practice for doing processing via Ajax, it should be written as a document here.
But to address your perception:
If the business/user wants to make updates and commit changes via Ajax, that has to be accommodated.
Certainly there are risks here and they should be mitigated.
I'm aware it's possible to call (Flow) Actions via UI events -- how does that handle commits/transid?
If you've got a work object in perform mode, with the lock... any commit done via Ajax will release that lock. So you need to re-acquire it. (and, mindful of our original question above, can we even handle transid above?)
Begging the issue, raised before, that users need to be cognizant of the lock status - Making optimistic locking safe
Updated: 2 Dec 2015 23:22 EST
Pegasystems
US
>>> I'm aware it's possible to call (Flow) Actions via UI events -- how does that handle commits/transid?
Either the actions don't commit because they wait for the final submit and then commit all the actions at once (so that all can be rolled back if need be), or if they do commit, they most likely refresh the screen so that the browser knows the new trans id. /Eric
Updated: 2 Dec 2015 13:45 EST
BNY Mellon
US
You probably should check that for sure.
Here's an example: Section pyFollowCase / Activity pzAddFollowerWorkParty, dating back to v6.
This is out-of-the-box functionality, showing how a built-in Ajax call can set the current user as a follower to the work object. It breaks your guidance, by calling an Obj-Save/Write-Now.
So what happens to the transid here? [my edit: the transid is untouched, because of Obj-Save with Write-Now, not touching the Commit transaction]
Moreover, the "let Pega handle the transaction management" is not well illustrated here. pzAddFollowerWorkParty commingles the transaction management (first: get the lock if we don't already have it; when complete: reacquire the lock). There should be a better example of how to this.
I'm looking at v7.1.5; not sure if this has been since cleaned up.
BNY Mellon
US
This remains a problem -- ran into this in a separate v6.2 app today.
The developers had a modal screen off a perform harness for adding comments... and they figured that a saving-and-committing-at-end was better than a bunch of Save-with-WriteNow's.
These changed the transaction id underneath, *without* updating the client. Re-raising my point from December -- have I missed it, is there a better way to communicate the Transaction ID to the client other than refreshing the whole page?
A call to ReloadSection needlessly reposts the old transaction id, leading to this error.
Possibly this is addressed in v7.2?
BNY Mellon
US
Can someone who understands how this works please respond?
BNY Mellon
US
After 30 days, I'm still pressing on this. The support articles are all over the map.
From: https://community.pega.com/support/support-articles/javascript-error-occurs-after-commit
The Ajax should return to the browser the value of pxRequestor.pxClientExchange (what exactly would the browser do with a plain ol' string?)
From https://community.pega.com/support/support-articles/getting-some-popup-error-message:
The ajax-called activity should "Select write now in the Obj-Save step, this will prevent the transaction id from getting changed."
Pegasystems
US
Hi Jon,
Are you having trouble solving a particular trans-id-mismatch error that you are getting ?
I looked at the two SA's that you cited above, and they both look correct, even though they give different solutions.
One talks about sending back the new transaction id after a commit. Commit causes the trans id to change, so sending the new transaction id back is important since the next time the browser talks to the server, it can pass the correct trans id to the server. When the old one is passed to the server is what causes the error.
Note that for the common path of a submit button causing work to be commited, the new trans id is passed back to the browser with harness that gets displayed following the submit.
However, the first SA you cite is for a situation where some commit is occurs other than in the common path, so that SA is showing one way to pass back the new trans id.
The second SA shows another way to avoid the error, which is not to do a commit at all. If the object being saved is not the primary work object, and no rollback is ever expected on that data, by using the "write now" checkmark on the obj-save, the data for that one object is committed without doing a server-wide commit and hence the trans id does not change, and therefore does not need to be passed back.
/Eric
BNY Mellon
US
I would like a new document authored to explain how Transaction ID is needed, when it's needed, and when it's not.
If no one else will start it, I will.
PEG
US
Hi Jon,
I've dealt with a number of transactionID mismatch issues over the past few years. My universal approach to all of them is to gather a Fiddler trace; I find the Fiddler trace is always 100% reliable in pinpointing the cause of the problem. (We recently emailed back and forth over such a case; your response was to withdraw the SR and resolve it without GCS involvement.)
These errors always fall into one of 3 categories:
- A clear Pega bug which needs fixing, either via local change or hotfix
- A clear customer bug which needs fixing via local change
- A not-so-clear bug which results from a race condition; the elimination of the race condition being a burden that sometimes falls to the customer Application to fix, and sometimes falls to Pega to fix; sometimes to both.
My experience has been that the majority of transaction ID mismatches come from the 3rd bullet, race conditions which are not managed correctly.
Regarding the use of an explicit commit in custom code, it is almost always (the "almost" is the loophole through which many trucks have been driven) a bad idea to do this. The potential for creating many different types of errors (and not just transaction id errors) is great, and the absolute need is rare, whenever you insert a "commit" into your code. The explicit commit is an easy tool to use, usually helping to avoid a redesign of the application, but almost always a bad idea.
Hi Jon,
I've dealt with a number of transactionID mismatch issues over the past few years. My universal approach to all of them is to gather a Fiddler trace; I find the Fiddler trace is always 100% reliable in pinpointing the cause of the problem. (We recently emailed back and forth over such a case; your response was to withdraw the SR and resolve it without GCS involvement.)
These errors always fall into one of 3 categories:
- A clear Pega bug which needs fixing, either via local change or hotfix
- A clear customer bug which needs fixing via local change
- A not-so-clear bug which results from a race condition; the elimination of the race condition being a burden that sometimes falls to the customer Application to fix, and sometimes falls to Pega to fix; sometimes to both.
My experience has been that the majority of transaction ID mismatches come from the 3rd bullet, race conditions which are not managed correctly.
Regarding the use of an explicit commit in custom code, it is almost always (the "almost" is the loophole through which many trucks have been driven) a bad idea to do this. The potential for creating many different types of errors (and not just transaction id errors) is great, and the absolute need is rare, whenever you insert a "commit" into your code. The explicit commit is an easy tool to use, usually helping to avoid a redesign of the application, but almost always a bad idea.
Regarding when to use and when not to use transaction ids, the simple answer is that it is extremely difficult and high-risk to determine when they are not needed. I remember about 30 years ago (yes, I can remember 30 years ago) working with a fellow who was hired because he was going to rigorously prove that our code was "correct." I don't think he got too many Christmas bonuses. Unless you can prove that nothing in the data in the POST can possibly ever be stale, no matter what has happened back on the server, you need a Transaction ID back on the Form. Not only for the initial design, but also for every single post-deployment change that is ever made, for all code in the system. For every field that might be added to a section, for every Declarative that might suddenly look at one additional piece of data, for every SOAP request that might provide one more additional piece of data, for every failure condition that might occur, you need to be able to confirm that your data back on the client is absolutely in synch with the database. Frankly, I would laugh at you if you ever made such a claim.
The Transaction ID says "sorry, you've committed something to the database, and the data you are attempting to POST is from the previous transaction. Refresh your data and try again."
BNY Mellon
US
Ron - yes, I filed a case commensurate with this thread. We couldn't reproduce the problem in prod. I pursued this thread here to get a better theoretical understanding I could share within.
And I feel Pega's explanations are still not coherent. Let's write a document that covers this comprehensively.
For a traditional workflow processing, where the state is important, transaction id's are necessary. But for any idempotent actions -- those that you can do repeatedly without any side effects: the state is untouched. As in the example I gave with pyFollowCase above, transaction ID is not affected, or even read. The example we ran into in prod was similarly about an idempotent action.
PEG
US
Hi Jon,
I don't have the knowledge relating to the philosophy of we to manage Transaction IDs within the Pega product. Although what you say about idempotent operations is absolutely true, I don't know to what degree (if any) Pega has directed effort to flagging and accommodating those actions. I will try to swing this by some other SMEs, although at this point nothing will happen until after the New Year.
Let me wish you a Happy New Year!
BNY Mellon
US
Thanks Ron, let me know.
BNY Mellon
US
Finally we were able to reproduce this problem in prod.
It looks like ReloadSection is what's passing the transid & frame.
What we found seems extremely obscure... and this being v6.2/sp2, it could be.
We seen in the error condition is that the POST is prepending this string "Error: connection has timed out." to the POST string.
Why would that be, we wondered? Where would that be coming from?
Our page is using DynamicSelects.
It seems that the Final HTML fragment rule DynamicSelect_Variables is including this:
<input type=hidden id=strDSTimeoutMessage value="<pega:lookup property='pxRequestor.pyMessageLabel' value='connectionTimedout' />">
That's a very old-fashioned way of storing variables in JS... why is this an input type="hidden"?
Would we expect to see adverse consequence if a variable is POSTed to PRServlet without a name?
(the transid does not match error might be one such thing... and if a ReloadSection call encounters that, what should happen.)
PEG
US
Jon,
The transaction id mismatch is detected when the POST first arrives at the Pega Platform. The command itself is not processed if such an error occurs. In the 7.1 releases, we return the error "Action is not allowed as it is outside the current transaction", and this is displayed to the user.
In the 6 series, we did not return this error; I don't think there was a uniform response on how we handled it, but it was not as clean as the above.
Are you still trying to determine WHY the error occurred? Or are you aware of why it did, and just unhappy that the system behaves the way it does?
FYI, also in the higher releases, for a UI Action set, a Finish Assignment appearing anywhere in the set is moved to the end, and the FA waits until all previous actions have completed (if it is an action that we can detect completion for) before it fires. The assumption being that there can be only one FA, and it is the last thing to fire. You may not want this assumption to be made, but that is how the code intentionally behaves.
BNY Mellon
US
Yeah, that's what we've been running into, in v6.x. We're going to override ActivityStatusExceptionHandler to log what the error is -- can't imagine why this never did that (relying on sending it to the user)
No quite sure about the root cause yet -- testing with POSTMAN, appears that sending an empty-string key should not cause this mismatch failure. fail the server.
Like I said above, we're a little closer to understanding what's going it. It appears to be happening in a situation with using multiple tabs for work ID's.
What would help us, it looks like, is turning debugging on com.pega.pegarules.session.internal.mgmt.base.ThreadUITransaction
BNY Mellon
US
I noticed a couple of additionally funny things here.
pxClientExchange is defined both on Code-Pega-Thread and Code-Pega-Requestor -- so that it can be referenced on both pxThread and pxRequestor. Holdonasec...
whoa, that sounds dangerous.
if the key point of Pega Threads is to isolate pyWorkPage/newAssignPage and their transactions... how prudent can it be to store this in on pxRequestor page? Or worse... getting it from the pxRequestor page?
If I search for "pxClientExchange" on a Pega7 system (latest I have here is v7.1.5), it is in the generated HTML of any a number of sections, and, horrors, it's referring to the value in the requestor page:
<%-- generate the trnasaction ID if it has been changed due to DB commit operations --%> <% if(tools.getParamValue("partialTrigger").equals("dragdropAuditTrail.pxResults1")) { String latestTransID = tools.getRequestor().getRequestorPage().getString("pxClientExchange"); String postedTransID = tools.getParamValue("pzTransactionId"); if(!postedTransID.equals(latestTransID)){%>
Pegasystems
US
There is a checkmark somewhere, I forget where, and maybe it was only until a certain version of Pega, that said whether data is stored on thread object or requestor object or both. Any of you remember what checkmark that was ? /Eric
BNY Mellon
US
Thanks. Curious to hear. Like I said a few months back, we really need an SME here to explain the ins and outs of this.
PEG
US
I have gotten this feedback from an SME:
Property on the requestor page is deprecated. Any attempt to keep them in-sync is legacy behavior. Only transaction ID properties on the thread pages are valid.
So the question becomes, do you know if this code you have found is actually causing an error? "Deprecated" is not the same as "no longer working", and legacy behavior just falls into the category of technical debt.
IF you can demonstrate that the Requestor reference is actually causing an error, then you should raise an SR and point to it as the culprit. Otherwise it is just something to keep an eye on.
BNY Mellon
US
Yes, I did raise an SR. I haven't quite connected the dots yet to reproduce the exact error, but we are working on that. I am still curious where in the engine the transaction ID is initially created, and why it might be pulling it from pxRequestor.
PEG
US
I don't know where it gets generated, but back in the dim mists of time there was only the Requestor page....so that was the natural home for it.
Pegasystems
US
Updated: 31 Mar 2016 12:53 EDT
BNY Mellon
US
X marks the spot!
"When checked, at runtime the system looks at the Thread level (pxThread
page) for the current values of certain system-maintained properties, that in V5.3 and earlier were maintained only on the pxRequestor
page."
Not sure how this was left unchecked...
BNY Mellon
US
This may have been sourced in SCM & CPM 06.02 applications leaving this unchecked as well.
BNY Mellon
US
Er, red herring. As we have discussed over email the "Place properties on thread page only" checkbox is unrelated to Transaction ID's.
AIG
US
posted transaction id '9e4984f5d63a0ea076051503146c8161' for frame 'pyWorkPage' DOES NOT match record '211093964c993cedccf6be7919f14643'
happens on the Approval flow action of the form which doesn finish assignment .
Any idea of how to fix this in Pega 62 Sp2?
Pegasystems
US
Ranjith, try this:
1) Run fiddler and record the error happening. Use pega log file to find the error you just recorded in fiddler. Identify the two transaction id's which we'll call B for bad and G for good.
2) On any fiddler records where B is passed to the server (look in the url in upper right on fiddler on "webview" for "transactionid") and B comes back from server (look in lower right on "text view" for "transactionid"), then B is still ok.
3) If D comes back and that fiddler record is the error message, then a recent commit caused the transaction id to change from B to G. Identify where the commit is being performed. If it's a commit in custom code that is not needed, try removing it.
/Eric
AIG
US
HI Eric
We did raise a SR and working with Ron.We have identified the root cause of the transaction ID issue.
Pelase refer to the SR SR-A24704: posted transaction ID does not match
Applying hotfix and will update the result.
in our case the transaction id was gnerated after finsihaed assignmnet and confirm harness loads ,during this time the declare expression fires for properties which still post old transaction ID.Get tragets activity was called after commit .
Hi Eric,
Adding on to Ranjith's response: this discussion is also being updated on this thread: If this error on log means slowness to the application
Adding it here to connect the two posts!
Regards,
Lochan | Online Community Moderator | Pegasystems Inc.