Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

VFP 6 Strange Problem

Status
Not open for further replies.

gomaram

Programmer
Mar 17, 2013
7
OM
I have application working on VFP6.0 and its installed on Server, giving access to users by Mapping Network drive. I use .app and application working very fine. Since last week having strange problem with application. while doing data entry, records are getting saved properly but document number which is getting increment by one from a database, does not work properly, it save records with some previously saved number (not exactly last one).

I am not able to trace problem but

1. is number of files / index open ? as i open all files (max 20) at begning of each action)
2. is matter number of users? (application working more than 100 users at a time)
3. i dont use .fpw
4. is no of files in each windows setting config.sys?

Please help anyone

Kind regards
Ram
 
An error typcally has a very direct reason in the code actually incrementing that document number. So what's the code incrementing that number? At what stage (when a document is saved or when a user begins entering a new document for example)?

A very easy way to have an autoincremnting number is the type integer (autoinc) since VFP8. If you make use of that you will not have a problem even in multi user environment.

Bye, Olaf.
 
Ram,

The most likely explanation is that there is something wrong with the locking of the table that stores the highest document number. However, without seeing your code, it's impossibble to know exactly where the error lies.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
Dear All

Thanks for reply, code is ok, its work properly but in between increment is not happening. LOCK etc working.

part of code -
If Upper(DOCNO_FLAG) = "AUTO"
Store 0 To mdocn
xnkey = Str(Year(mdocdt))
Set Exact Off
Sele docmast
Seek xnkey
If Found()
If Rlock()
Repl bR With (bR + 1) In docmast ** here is new no for doc, but while saving sometime it take some old number instead new
Flush In docmast
mdocn = bR
Unlock In docmast
Endif
Else
Appe Blank In docmast
Repl Year With Year(mdocdt) In docmast
Repl bR With Year * 1000 In docmast
Repl bR With (bR + 1) In docmast
Flush In docmast
mdocn = bR
Endif
Mdoc = Len(Alltrim(Str(mdocn)))
mdno = Padl(mdocn, 7, '0')
Mdocno = mdno
Else
mdno = Mdocno
Endif

 
This part seems ok. Theoretically twoi users miught read the same bR, but that shouldn't happen too often. What's still very unclear is when you do it, and whether that happens wrapped in a transaction the users may also rollback. Then your counter can also roll back.

Bye, Olaf.
 
Ram, looking at your logic, it seems that no action will be taken if you succeed in finding the record but the RLOCK() then fails. As far as I can see, in that case the counter won't be updated. That's presumably not what you want.

Put another way, you need an ELSE condition to go with the IF RLOCK().

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
Well spotted, Mike. There is no handling of the case you can't rlock. That easily explains identical docnumbers and the detection of them then may be later, when this isn't just one off the current number.

Bye, Olaf.
 
Dear Mr Mike,

Thanks and gr8 reply, i will check with else condition if not record locked.. should i put loop? (waiting for lock...)

Regards
 
I suggest you start by doing SET REPROCESS 2 SECONDS. Since a queue of locks will rarely take that long, that should solve the problem. But if it doesn't, then place the IF RLOCK() in a loop; in other words, keep trying until the lock succeeds.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
Dear Mr Mike

I do have reprocess -1 but i will put loop n check as rlock does not takes so much time
will update you in day or two

kind regards
 
OK,

If nAttempts is –1, Visual FoxPro attempts to lock the record or file indefinitely. You cannot cancel the locking attempts by pressing the ESC key, and an ON ERROR routine is not executed.

That would mean you always wait for the lock and RLOCK always returns .T. or your app will stop and hang in the worst case.

But there is a reason this could fail SET REPROCESS is one of the settings you have to do per datasession, see the topic on SET DATASESSION.

Putting RLOCK in a loop may help, you could do:
Code:
DO WHILE NOT RLOCK("docmast")
  DOEVENTS FORCE
ENDDO

I would think about an exit strategy by a timeout, for example. With SET REPORCESS TO -1 you optimistically expect you always will get a lock sooner or later.

In my old VFP6-7 days I also learned the hard way an RLOCK is not as good as an FLOCK. Although you have a counter per year in a specific record, that year is the current one, so unless that app is used at midnight new years eve you'd only lock the same record at each client anyway, a concurrent creation of a newxt document number of different years would be possible, but you don't do that. Then you can also do an FLOCK. That also would surely improve the lock quality.

Bye, Olaf.
 
Hi Mr Mike
Sorry, i m back. earlier i had code as below and with same problem

IF (DOCNO_FLAG="Auto")
store 0 to mdocn
xnkey = str(year(mdocdt))
sele docmast
seek xnkey
if not eof()
DO WHILE .T.
IF (RLOCK())
mdocn = bR + 1
repl bR with (bR + 1)
UNLOCK
EXIT
ELSE
WAIT WINDOW "Waiting for lock...!"
ENDIF
ENDDO
else
DO WHILE .T.
IF (fLOCK())
appe blank
repl year with year(mdocdt)
repl br with year*1000
mdocn = bR + 1
repl bR with (bR + 1)
UNLOCK
EXIT
ELSE
WAIT WINDOW "Waiting for lock...!"
ENDIF
ENDDO
endif
Mdoc = LEN(ALLTRIM(STR(Mdocn)))
mdno = PADL(MDOCN,7,'0')
Mdocno = Mdno
ELSE
MDNO=MDOCNO
ENDIF


Later then changed to other code, please advise

Regards

 
Gomaram,

Here is some code that works well for me.

CODE/
sele a_sysdat (file that holds the incrementing number)
* int1 = field that holds number
* the following just keeps the number less than 8 chars
Store IIF(int1 + 1 < 100000000, STR(int1 + 1,8,0), STR(1,8,0)) TO hldnumber
* Lock Files
Store 0 to cntlock
Do WHILE .T.
cntlock = cntlock + 1
Unlock ALL
If cntlock > 20
Exit
Endif
Select a_sysdat
Do p0rlockd ( record lock routine with display)
If .NOT. lockedr
Loop
Endif
Select mast ( the file that holds new number )
Do p0flockd ( File lock routine with display)
If .NOT. lockedf
Loop
Endif
Exit
Enddo
If cntlock > 20
Wait wind 'Error locking files retreiving New number, will abort after press any key'
Unlock ALL
Else
* Get New record using new record Make sure it doesn't already exist in MAST
Select mast
Seek hldnumber
Do WHILE .NOT. EOF()
Select a_sysdat
Replace int1 WITH VAL(hldnumber)
Store IIF(int1 + 1 < 100000000, STR(int1 + 1,8,0), STR(1,8,0)) TO hldnumber
Select mast
Seek hldnumber
Enddo
Select a_sysdat
Replace int1 WITH VAL(hldnumber)
Use IN a_sysdat
* continue with update
endif
* do not continue
close files
return
ENDCODE/
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top