The default value for SET REPROCESS is 5 locking attempts in VFP OLE DB provider. And yes, it causes above exception sometimes. Obvious work around is:
1) set reprocess to longer interval as Olaf suggested
2) catch the exception and retry the insert attempt
3) insert records in a stored procedure which can handle manual locking and returns success/failed flag
4) insert records from each connected user into a separate table and create standalone process which inserts records from several standalone tables into the "main" table
If you are inserting records to one table only then transactional processing does not help.
Main Topics
Browse All Topics





by: Olaf_DoschkePosted on 2009-11-06 at 15:24:03ID: 25763967
Your assumption is right. As we talk about an insert into here, vfp is trying to lock the head of the dbf automatically before inserting, after getting the lock inserts data and then unlocks the file. And vfp does retry if a lock doesn't work at the first time. The setting for this is REPROCESS. Via oledb provider you can also send a SET REPROCESS and change that setting. At the default setting vfp is trying locks indefinately, therefore you'd not get the error due to this behavior, some inserts just might take longer.
The other problem you could have in accessing a dbf table is, that someone has an exclusive lock, opened the dbf exclusive, but then you get an error 'File access is denied'.
So 'File is in use by another user' only happens, if you set REPROCESS to some setting limiting attempts, which makes sense in a web app, as you will need to do things within a timeout.
What you perhaps should do is send a command like this to the oledb provider and see how REPROCESS is set:
Create Cursor curResult (nReprocess I)
Insert Into curResult Values (Set('REPROCESS'))
Insert Into curResult Values (Set('REPROCESS',2))
SetResultSet('curResult')
To execute these three commands in one ExecuteNonQuery, execute EXECSCRIPT("..."). the result should be a dataset. Let us know if that's different from 0. the value of the second record will tell you what the value in the first record means, if it's N attempts or N seconds. 0 in the second record means it's attempts, 1 means it's seconds.
The best approach for a webapp might be to set it to 3 or 4 seconds and have error handling of such a message to report a failure if the insert doesn't work. And overall do manual transactions by sending BEGIN TRANSACTION and END TRANSACTION or ROLLBACK, if you do more than a simple insert it might not be good to fail half way, then better ROLLBACK.
Bye, Olaf