FairCom DB is designed to simplify the transition between different platforms or operational models. For the most part, changing models is simply a matter of compiling new libraries and re-linking your application.
However, some concepts are specific to one operational model. The transition can be made smoother by reading the entire section titled Operational Models (Operational Models, /doc/ctreeplus/30177.htm) in the FairCom DB Developer's Reference Guide.
Changing from a single-user application to multi-user (either standalone or client/server) introduces the possibility of multi-user interference. This is prevented by proper locking techniques and/or transaction processing (available with the FairCom Server). See Multi-User Concepts and Data Integrity in the FairCom DB Programmers Reference Guide for more information.
A single-user standalone application can support transaction processing. If switching to multi-user standalone, transaction processing will not be available. Transaction processing is possible when migrating from single-user standalone to multi-user client/server, since both support transaction processing. In fact, this simplifies the locking issue since locking can easily be added to existing transaction processing calls. For example, replacing Begin(ctTRNLOG) with Begin(ctTRNLOG | ctENABLE). See Adding Transaction Processing and Data Integrity in the FairCom DB Programmers Reference Guide for more information.
A frustrating scenario, relating to users migrating from FairCom DB Multi-User FPUTFGET model to the FairCom Server, needs to be discussed. The dilemma relates to users of the FairCom Server receiving FCRP_ERR (14) error codes when opening server based files. The message text for the FCRP_ERR (14) error states “File corrupt at open”. Keep in mind that this scenario only exists due to a power loss, a machine being tuned off without stopping the server, or a miscoded program that does not close its files, only when the FairCom DB developer chooses NOT TO implement transaction control as suggested for the FairCom Server.
The FCRP_ERR (14) did not exist in the multi-user mode, so therefore a scenario was created in which customers, who have been running successfully for years, upgrade to the FairCom Server for stronger data integrity, start to receive “corrupt data errors”. The error is due to either the user shutting off the power to their server computer or an application not properly closing its files. Under FPUTFGET, the end-user (or the application) could get away with this. Now they get errors. Can you imagine the end-user frustration?
First, it is in order to discuss the FCRP_ERR (14) error. In FairCom DB single-user mode and under the FairCom Server, a file update flag is maintained within the header of each file. When a file is written to, in any manner, this flag is set to indicate the file has been updated. When the file is closed, this flag is re-set, indicating that the application has properly closed the file. Any attempt to open a file which has been marked update and which has not been properly closed, will result in a FCRP_ERR (14) error. The FairCom Server has no way of knowing the state of this file, and therefore must return this state back to the application as an integrity error/warning.
In FairCom DB’s multi-user FPUTFGET mode, the write operation is immediate secured to disk and therefore this flag is not maintained nor considered. An error 14 simply did not exist under FPUTFGET. An application could exit without properly closing a file, or a computer or file server (i.e.: NetWare Server) could be powered off (switched off by end-user) without causing any immediate catastrophic results for the customer. Perhaps the last “enter-key” entry at the time of power loss could be out of sync, yet the entire file would not be in question.
So now, take the scenario where one has a user, who has been running for years under FPUTFGET, who upgrades to the FairCom Server. As a reasonable half-step, the developer chooses to start with the application running in the same matter as it did with FPUTFGET, and intends to add the necessary code changes for transaction processing at a later date. The developer’s efforts are easy, simply re-link the application with the FairCom DB Client library instead of the FPUTFGET library, and it is ready to go. Now, the updated application and new FairCom Server are deployed at the customer’s site. The customer proceeds to operate in the same manner before, now complimented by the Client/Server architecture, experiencing less network traffic, and better performance due to the Server’s data caches. Now, as before, the customer “flips the switch” at the end of the day, just like they have done for years (without you knowing it). CATASTROPHIC situation. Now all data/index files open at the time are in question. Because of the FairCom Server’s caches, not just the last “enter-key”, but the entire file is now undefined. A FCRP_ERR (14) is properly returned the next time the file is opened. The user, who is used to coming in the next day, switching on the machine and going back to work, was now calling the developer’s tech support line reporting numerous error 14 messages and corrupt data.
The following solutions are available to solve this dilemma:
In addition, a warning message helps the developer recognize this vulnerability. If a server does NOT have COMPATIBILITY WTHRU_UPDFLG in its configuration file, and if non-transaction files are opened without ctWRITETHRU in the file mode, then a warning will be issued in CTSTATUS.FCS concerning the vulnerability to FCRP_ERR (14) if a server is not shut down properly. The warning is only entered into CTSTATUS.FCS one time after each server startup when a vulnerable file is detected. The keyword STATUS_MASK WARNING_FCRP_ERR may be added to the configuration file to eliminate this warning message.
See the COMPATIBILITY PREV610A_FLUSH keyword for a good balance between performance and recoverability.
Adding transaction processing to an application permits complex, atomic updates and automatic recovery in the case of software or hardware failures. Transaction processing can be added with the transaction processing sub-API or with SetOperationState().
To add efficient transaction processing, use the transaction processing sub-API described in Data Integrity in the FairCom DB Programmer's Reference Guide. If your application is already prepared for multi-user use, replacing LockISAM(ctENABLE) calls with Begin(ctTRNLOG | ctENABLE) and replacing LockISAM(ctFREE) calls with Commit(ctFREE) or Abort(ctFREE) calls, depending on the status of the transaction at that point, is a simple method of implementing transaction processing. See ctixmg.c for an example and Data Integrity for more details.
To add transaction processing quickly, though not in the most efficient manner, use SetOperationState() with the OPS_AUTOISAM_TRN mode. This performs a transaction around each ISAM update. See SetOperationState (SetOperationState, SetOperationState) for more details. This method does not effectively lock updates. You will still need to use some form of locking control. Consider the OPS_LOCKON_GET mode for SetOperationState() to minimize network traffic.
Once the application supports transaction processing, add either of the transaction processing file modes, ctTRNLOG or ctPREIMG, to the data files requiring transaction processing using the UpdateFileMode() function. Index files must be rebuilt to add or remove transaction processing. For additional information on Transaction Processing, please see Data Integrity.
Switching to a multi-threaded, ctThrd, library is similar to adding transaction processing: superficially very easy, but with many implications.
As a minimum when using the ctThrd library, you must implement the ctThrd API. You must call ctThrdInit() before initializing FairCom DB, just as you must initialize c‑tree before calling any other FairCom DB API functions.
Any new threads that call FairCom DB API functions must be created with ctThrdCreate() or attached with ctThrdAttach().
In the Multi-threaded Standalone model, do not mix the FairCom DB Instance API (RegisterCtree(), etc.) with the ctThrd API. Each thread is its own instance of FairCom DB, and handles instance switching via the ctThrd functions. This is not an issue with the Multi-threaded Client Model.