Problem : VFP – File is in use by another user

Problem : VFP – File is in use by another user

I have multiple users inserting records inside a FoxPro database throuhg an ASP Application.

It is very common to have multiple users inserting records at the same time and, when this happens, they get this error message:

Exception of type ‘System.Web.HttpUnhandledException’ was thrown.: System.Web.HttpUnhandledException: Exception of type ‘System.Web.HttpUnhandledException’ was thrown. —> System.Data.OleDb.OleDbException: File is in use by another user.

Seems like FoxPro is locking the file until it finishes inserting the new record which is stopping my other users to insert/update anything.

any ideas how can I work around this issue?

Code Snippet:
Dim con As New OleDbConnection(System.Configuration.ConfigurationManager.ConnectionStrings(“FoxPro_DB”).ConnectionString)
Dim sql As String = “insert into tablename (clientid, Tablename) values (‘clientid’,’table’)”
con.Open()
Dim command As New OleDbCommand(sql, con)
command.CommandType = CommandType.Text
command.CommandTimeout = 0
command.ExecuteNonQuery()
command.Dispose()
con.Close()

Solution : VFP – File is in use by another user

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.