FileFlex 3 comes in separate single- and multi-user editions. The single-user edition is designed to support the use of the database by one person at a time. The multi-user edition is designed to allow many people to access the database concurrently. There are a number of special technologies required for concurrent database access, the most important being "locking".
The idea behind "locking" is that while one person uses certain data, he locks it. This means that other people can't get to that data while it's locked. Later, when the person stops using the data, he unlocks it.
There are two types of locking used in FileFlex: file locking and record locking. File locking is pretty brute-force. When you lock a file, you lock the entire file. Period. No one can get to that file while you're using it. Typically you'll want to lock the entire file (using the DBLockDB command) when you're doing some form of maintenance, like rebuilding an index.
The other form of locking, the one that's key to making your multi-user application work properly, is called "record locking". Record locking allows you to lock a single record at a time. This is much more practical in a multi-user environment where you're presumably working on a database of many records. Each user works on a single record, that record is locked for that one user. When the user is done with the record, it is then unlocked and remains unlocked until another user claims it.
There is an issue of "deadlock" in all multi-user applications. Deadlock occurs when two or more people are fighting for the same locked record, at the same time. To prevent deadlock, make sure that all files are ALWAYS locked and unlocked on all machines in exactly the same order.
The following new functions are available for the multi-user edition of FileFlex:
These functions are only available in the multi-user edition. Attempting to call them in the single-user edition of FileFlex will generate an error.
Setting the Sharing Mode
In FileFlex 3, the way a file is opened determines how it can be shared among users. There are three types of sharing:
A key difference between the single- and multi-user editions of FileFlex is that the single-user edition always opens files exclusively. Single-user editions of FileFlex also are smaller since all the code for sharing information is not compiled in.
To set the sharing mode, use the FileFlex function DBSetShared. DBSetShared takes a single parameter: the sharing mode. This is a string corresponding to the type of sharing mode you want for the file. The three mode strings are:
The order in which you call DBSetShared is very important. You must call it BEFORE you open any database or index files. Here's an example (be sure you check result codes):
put DBSetShared("rw") into theResult put DBUse("VIDEO.DBF") into dbID
To change the sharing mode for a file, close the file, set a new sharing mode using DBSetShared, and then re-open the file.
Locking a Record
When you want to lock a record, call DBLockRecord. DBLockRecord locks the current record in the current database. If you've already locked the file using DBLockDB or previously locked the record, FileFlex returns success. FileFlex automatically unlocks every other record or file (except the subject record's own file) when a new DBLockRecord is called. This technology also helps to prevent deadlocks.
There are no parameters to this function. Simply move to the record you wish to lock and execute the function like this:
put DBLockRecord() into DBResult -- your record processing code here put DBUnlock() into DBResult
When you call DBLockRecord, it will wait until the record is available to be used. FileFlex will attempt to access a locked file or record at approximately one second intervals. It will continue to do so until it gains access. If we find this becomes a problem, in a future version we may allow you to set the number of access attempts or time.
When you're done using that record (and you should keep the record locked for as short a time as possible), call DBUnlock to free it up.
Locking An Entire Database
The DBLockDB function locks an entire database at once. It operates on the currently selected database and has no parameters. Whenever you're running a multi-user system and you want to do some sort of serious maintenance, you should call DBLockDB like this (of course, always check result codes):
put DBSelect(theDB) into DBResult put DBLockDB() into DBResult
Unlocking a Database
If you used DBLockDB to put a lock into a file or DBLockRecord to lock a record, DBUnlock will unlock it. DBUnlock does not unlock a locked record. Rather, the next time you call DBLockRecord, the DBLockRecord function will unlock any other records it has locked and attempt to lock the current one.
To unlock a locked database file, do the following (checking result codes as you go):
put DBSelect(theDB) into DBResult put DBUnlock() into DBResult
There's one last, very important, multi-user function provided by FileFlex. This function, called DBRefreshRelation is used to keep all the relations current. In a multi-user environment, you're going to have a lot of people updating data. If you've created a relation (a virtual, combined table), the information represented by the relation might change.
DBRefreshRelation, which takes no parameters) forces the complete updating of an active relation. To be sure you've got the very latest information, the query relation has to be rebuilt. So, if you've done a relational query and some time has passed, it's good to call DBRefreshRelation in case others have made some important changes.
Obviously, this function will take some time to execute and you probably don't want all the users calling it. So, if you use it, keep careful consideration of optimization issues.
Here's a short example (as always, check the result codes):
put DBRefreshRelation() into DBResult
Discuss this chapter on the FileFlex Boards.