Cannot commit to server Error

I am getting a notification: “Cannot commit to server. Cannot commit - record is not locked.” There is something in my code that is triggering this when I attempt to add a record via a procedure in a shared database in the background. In other words, I am using code similar to:

SetActiveDatabase “BackgroundDatabase”
AddRecord
Save

It appears that the error is generated with the Save statement. The code worked as a single user database, but issues the error now that the database is shared. Any ideas?

I tried this exact same code on my client/server system and it worked fine. So I think whatever is causing this problem, it’s not the code.

Hi James, I have seen this error message also and I have had a recurring problem for months (I was a very early beta tester of 10.2). Unfortunately, I don’t know the precise answer to what occurred, but I have a hypothesis for what is happening and how to fix it, which I will share in the hopes that others may be able to contribute to the discussion.

The fact that this worked fine in single user mode is strong evidence that the client/server operation is implicated. The error message reflects a server issue. Committing a record, I think, refers to modifying a record already on the server.

I can quite reliably reproduce the error you have reported by making one change to your code: I added an assignment after the addrecord before the save statement.

First, I suggest you remove the Save statement and see if it works. From our classes you will recall that the server is automatically saving changes. First to the journal and then to the hard drive after a user controlled time delay. So the Save statement here theoretically is unnecessary.

Here is the code that failed when I tried it, starting from my database called Navigator:

Setactivedatabase "DutchVocabulary"
addrecord
Dutch="Bonjour"
try
    save 
    alertsheet Dutch+" TimeStamp is "+info("serverrecordts")+" ID is "+info("serverrecordid")
catch
      alertsheet Dutch+" TimeStamp is "+info("serverrecordts")    
endcatch

I get the same error message you reported. Initially, I see a new record on my client database with the assignment there (Bonjour appears in the Dutch field; I know its French, but the Dutch use a lot of foreign words.). When I synchronize the database, the Dutch field changes to empty. So now there is a new record, but it is empty and the alert never appears. Seems like the procedure has been interrupted by the error.

I am quite sure now that this error is occurring frequently at my client’s office where people are using PanX 10.2 with several shared databases. Quite often I find that empty records have appeared without explanation (until now).

If I remove the Save statement from my procedure, I do not receive the Cannot Commit error message and I do get the alert with ID 11768, TS 986. This matches the data that appears in the instrumentation log. If I now synchronize the client, the data is present. In other words, the procedure works properly with the Save statement removed.

I conclude from this data that the save statement is causing the problem in this context.

In the first case, with Save statement included, instrumentation log has this block (which is different when the save statement is removed):

CLIENT COMMIT RECORD ==================================================
[CLIENTCOMMITRECORD] rid: 2
[CLIENTCOMMITRECORD] hostDatabaseName: DutchVocabulary on hostServer: TGC PanX Server
[CLIENTCOMMITRECORD] Request commit. rid: 2, sessionID: 7
[CLIENTCOMMITRECORD] === DICTIONARY xreply ============
[CLIENTCOMMITRECORD] STATUS=“ERROR”
[CLIENTCOMMITRECORD] INFO=“Cannot commit - record is not locked.”
[CLIENTCOMMITRECORD] LOOPBACK=“”
[CLIENTCOMMITRECORD] === END OF DICTIONARY xreply ============
[CLIENTCOMMITRECORD] Commit failed: Cannot commit - record is not locked.

So what is happening? My hypothesis is that the problem is related to the run loop. When a record is added in a shared database, there are communications back and forth between the client and the server. When the client code encounters a save statement, the run loop is implicated. (I think this will be a topic in a future class.) See

Display-updates and save-actions cause another branch of code to be run outside of the main procedure code. This could be interfering with the back and forth communications that must occur in order to add a record to the server. That is, the server expects a response from the client but does not get it because the client is busy with a save operation.

The problem may be cured by adding a wait 0 statement immediately before the save statement. I think, but am not sure, that this will cause the prior code to complete its execution before the save operation begins. This strategy is discussed in the Run Loop pages. When I tried this, I got the alert I expected with TS of 1005 and ID of 11770. Now when I synchronize the data, the record is retained and no error message appears. The log shows that the original TS was 1004; after the assignment, the TS has updated to 1005, as expected. And the Commit record log block ends with “Commit finished.” and no error.

So the addition of a Wait 0 statement before the save statement cured the problem.

James, I am so glad that you reported this issue and I think I have a better understanding now and know that I am not crazy, having seen the problem numerous times.

Yeah! You and I have been chasing this for a while – well finally now we have code that I can run and duplicate this problem. In fact, it fails every time, which hopefully means that now I can chase it down and fix it. Ok, I can immediately see that it is trying to commit the wrong record. More to follow.

Ok, I think this is now fixed. :slight_smile:

In the meantime, you can fix your code by adding an unlockrecord statement before the save statement.

setactivedatabase "DutchVocabulary"
addrecord
Dutch="Bonjour"
unlockrecord
save

Many Panorama statements automatically unlock, unfortunately, save is not one of them (but it is now).

On further study, the save statement actually was unlocking the record, but it wasn’t doing it correctly. Hence the problem. In any case, the issue now appears to be resolved.

I take it from your messages that my hypothesis about the run loop was incorrect; it did not explain the failure. True? That would be good know so I can find a different windmill to tilt at.

I am still trying to stop crashes that occur in similar code, but I don’ have a Save statement, so that is not the explanation.

Does what you have found here help solve the earlier problem I posted under the heading “Crashing PanX way too often”?

Hello Jim, That seemed to do the trick. We are up and running. Much thanks!!!

I would still try putting an unlock statement in immediately after your code finishes modifying the record.

Sorry, I have no idea.