Assignment Not Working in Shared Database

I am reposting this topic because after I corrected my typo, I still encountered a serious problem.

I am having trouble making a simple assignment to a field with a procedure in a shared database.

When I have this code in a procedure

Find [search criteria]
[Fieldname]=[some value]

it does nothing; seemingly ignored. The procedure stops when it encounters the assignment statement. If I run this code in a separate procedure, I see a message in the procedure window;

“Cannot modify field [Fieldname], record is locked by another user.” [That cannot possibly be true in this instance.]

I tried locking the record, then making the assignment, then unlocking it. That did not work. It gives a message that the record is locked by another user. I don’t know why the record would have been locked at all before trying to make the assignment. The Server Admin does not show a locked record, before, during, or after the procedure runs and nothing in the procedure, as I understand it, has locked the record.
It seems like the Find statement locked the record that it found but it was not associated with me, so I couldn’t change it.

Does this problem only happen after a find statement? Or have you tried assignments in any other situation. Anyway, I will look into this.

FYI, I did a quick test, and could not duplicate this problem. It’s kind of puzzling, because there is no code in the find statement to lock a record. The lock happens when you do the assignment.

Essentially Panorama treats:

Field=value

as if it was

lockrecord
Field=value

So you ran the assignment twice, once in a larger procedure, and once in the separate procedure? I wonder if somehow the first time it locked the record before the procedure stopped.

The procedure creates a dictionary with the initials of employees and the balance of the person’s vacation time. That works fine when the assignment statements (two of them) are commented out. The Server Admin window never shows a locked record in that case.
If I add the assignment statement, Panorama crashes and I then see in Server Admin that there is a locked record. (So it appears the Assign statement did lock the record.)
When I restart and reopen the database, the Server Admin still shows a locked record. At that point, if I run the procedure and include code to display the error, I get this message:


But suppose I close the database and wait a couple of minutes, the record unlocks, according to Server Admin. If I repeat the steps with no locked records, Panorama crashes every time; I suspect that it is crashing when it reaches the Assignment.
I did switch to a different server, and run a procedure that finds a record then assigns a value to a field. It worked very slowly, but it eventually, after perhaps 20 seconds, make the assignment.
As for the first database, I am going to delete the assignments and figure out some other way to accomplish what I want to do.

I detached the database from the server and the procedure ran as expected and made the assignments. I am moving on to other things, so this is not of any important to me at the moment, so I don’t know if you want to pursue this now. I can post the entire procedure if you like; you won’t be able to run but maybe it would give you a clue of what is happening.

So are you saying this particular code crashes when the assignment happens? Have you managed to us assignment at all in other places without problems? Yes, I would like to see the entire procedure.

Jim, here is the procedure where the problem assign occurs. Originally, the procedure built a dictionary; it went through a loop for each employee’s initials. Later I added to the loop the assignment of the accrued vacation time and the date and time of the calculation; that is where the failure occurred. If I remove the assignment, the procedure works fine.

/* This procedure builds a dictionary of current employees and the current balance of vacation time. The dictionary is contained in fileglobal variable fgvacbal. */
/* This procedure is not currently in use and did not do what I had hoped. */

let lvsupernow=superdate(today(),now())
selectall
let lvtkp=arraybuild(cr(),"TimekeepersforBP",{Initials},{Current="Y" and Associate="Y"})

let lvvacbaldict=""
let lvmonths=""

looparray lvtkp,cr(),lvinit

    Find Initials=lvinit and StartDate>date("1/1/85")

    if StartDate<year1st(today()) or not info("found")
        lvmonths=val(datepattern(today(),"mm"))
    else
        lvmonths=val(datepattern(today(),"mm"))-val(datepattern(StartDate,"mm"))+1
    endif

    let lvcarryover=aggregate({CarryoverVacation},"+",{Initials=lvinit and WorkDate>=year1st(today())})

    let lvvacused=aggregate({Vacation},"+",{Initials=lvinit and WorkDate>=year1st(today()) and Submitted="Y"})/8
    let lvaccrued=round(lvcarryover/8+min(lvmonths*1.5,15)-lvvacused,.1)     //Carryover vacation plus vacation earned minus vacation used gives the current balance of vacation in days.
    lvvacbaldict=lvvacbaldict+","+lvinit+","+lvaccrued

    //VacationBalance=lvaccrued  [this is the line where the error occurs]
    //BalDate=lvsupernow   [same issue] 

endloop

lvvacbaldict=(arrayfilter(lvvacbaldict,",",{||"||+import()+||"||}))[4,-1]
letfileglobal fgvacbal=""
execute {initializedictionary fgvacbal,}+lvvacbaldict

So VacationBalance and BalDate are integer fields, is that correct?

Also, have you been able to do assignments in any other code in a shared database? Or is this the first time you’ve tried?

I have a thought about this procedure not doing what you hoped. I’m not 100% sure what you hoped, but I think the logic would be clearer if you put the

letfileglobal fgvacbal="" 

line above the loop, and then used setdictionaryvalue each time thru the loop, like this

setdictionaryvalue fgvacbal,lvinit,lvaccrued

instead of trying to build up a big string and then using initializedictionary. I think it actually would be faster as well (slightly), but more importantly, I think the code would be easier to follow and debug.

My solution would put numeric values in the dictionary, which is a bit different than what you are doing. If you wanted text values, do this:

setdictionaryvalue fgvacbal,lvinit,str(lvaccrued)

VacationBalance is an floating point number (people can have a fraction of a day), and BalDate is an integer, for storing a supernate.

I certainly use assignments frequently and some of the shared databases I have begun testing use assignment. I think are working; I just checked a couple of them and they look correct. I will do some furthering to confirm that they are working correctly and let you know if I find other places where they do not.

Thank you for your suggestions on the dictionary and reorganizing the procedure. I have never used a dictionary before even though I have known about them since the course. I did not remember the setdictionaryvalue statement, but, from now on, I will.

I created the dictionary so I could use it in an arraybuild statement. The array has the time used for each employee in various categories. In the vacation column, I wanted to include the accrued/balance of vacation time. I thought I could extract the balance from the dictionary in the formula used to build the array. It was not working and I put that aside, but I will try again. My comment about not working referred not to the subject procedure but the other one trying to create the array.

This has been an annoying problem and frustrating. I have had many, many crashes. Will persist in trying to solve this, though.

In a very simple shared database, I wrote a simple procedure that would make an assignment to a text field, a date field, and an integer field in that order. Those worked correctly.
The results are not affected by a find statement.

That’s good news. I think I’m going to skip looking further into this for the moment. I’m trying to wrap up b6, which has taken much longer than I hoped, but on the other hand I’m pretty excited about and want to get it out there for you to try. So I think I’ll leave any extensive look into record locking until after that is released.

Once you learn how to use them, dictionaries can be very powerful tools. I never could have gotten Panorama X Server done without them.

Good idea.

Hi Jim, assignments are continuing to fail periodically and cause PanoramaX b6 to crash. In a NON-shared database today, in the one database that has been in service for two years, it began crashing when it reached an assignment. The exact same database ran without a problem on my computer, but on the user’s computer (a one year old iMac) it failed 10 or 15 times in a row. I embedded some console statements to try to confirm where the failure occurred, and indeed, it happened with an assignment. But then it began working again while I was still testing to confirm the failure point.
I can’t remember where you are on the issue; is this one still under investigation? Of all the issues, this one is the most problematic. At least I can say it occurs only perhaps 5-10% of the time. The problems related to syncing can all be worked around, but not this one. And this issue has just begin with 10.2. The procedure that failed today has been in use for a long time without a problem.

At the moment, I don’t really having any basis to investigate. Assignment in 10.2 definitely has new code for record locking, but that should not affect a single user database.

It sounds like it is crashing in the same place when it does crash, not random assignments but a specific one. Is that correct? Is the value that is changing displayed in any kind of form object? Especially something fancy like a Text List, Matrix, etc. It could be that the crash isn’t in the assignment itself but when Panorama displays the changed value.

After our discussions a few days ago, I realized that it was probably going to be problematic for you to coordinate with all your users to enable and submit instrumentation logs from all of their computers. I suspect that some of these users are not very technical, right? So I came up with an idea that will allow all of the logging to coordinate thru the server, which I have implemented over the weekend. You’ll be able to control the logging from the server computer, and the users won’t have to do a thing! I think it will be MUCH easier on your end, and will produce better data for me to examine. Of course all of this keeps pushing out the release of b7, which is frustrating all around. But I think it will be worth it in both the near and far term.

I understand that you have to have information available to work on an issue, and an intermittent issue on a customer’s machine that you cannot reproduce is a big problem. But…I have confirmed problems with assignments in three different procedures. In the one today, the values are not displayed at all. No text lists, and I never use matrices. Given the console statement before and after the assignment, it seems to be certain that the assignment statement is causing the crash. The first console statement arrives In the console; the second one one does not. I will keep doing the best I can to understand what is happening and tell you if I find something interesting.

None of the users are very technical. So your plan sounds like a very good idea. I look forward to b7 when it is ready, but I am not in a rush.

I was just pointing out that there are two phases to an assignment – actually changing the value, and then displaying the changed value. From my point of view those are quite distinct. Your console statements can’t really tell which phase is causing the problem.

I would assume that you have many, many procedures with assignments. Is that correct? Do you keep randomly finding crashes with more and more of these? It must repeat if you have had the chance to put in console statements.

Assignment statements are one of the earliest parts of Panorama, that code goes back to 2013 or 2014. So I am really mystified that crashes would start happening in that very old code. There are changes for record locking but I actually did that about 2016, and all of the released versions of Panorama have that code. I haven’t heard of other problems with assignments, which in general I would think would make Panorama unusable.

I look forward to b7 when it is ready, but I am not in a rush.

Thank you! I put enough pressure on myself.

My instrumentation system is nearly complete, even with 23 pages of documentation (which is not complete yet, so it will be longer). However, currently it does not provide the ability to monitor Objective-C code, only Panorama code. That won’t help with your assignment problem, and possibly not with synchronization problems. I think I know how to extend the instrumentation system to do that, but that’s going to take even longer!! This is driving me crazy. So I definitely appreciate your patience.

My suggestion, for what it’s worth, is to defer for now addressing the assignment issues that I have identified. You have offered some strong reasons to doubt my hypothesis.