How Client-Atomic Transaction Processing Works
Once the begin_transaction function has been executed, all database changes are written to a virtual transaction file. There are actually only three operations that have to be saved in the transaction file:
- Editing a Record: The old contents of the changed columns, the record number, and the table number are saved.
- Deleting a Record: The whole record, the record number, and the table number are saved.
- Writing a New Record: The record number of the new record and the table number are saved.
When the transaction is committed, the current contents of the transaction file are discarded. The transaction-abort process is more complicated; it involves reading the transaction file backwards sequentially. As each database change is encountered, the appropriate action is taken to back out the change:
- New records are deleted.
- Deleted records are restored (with the original record numbers).
- Edited records are changed back to their original contents.
Therefore, the databases are put back into the exact state they were in prior to the transaction. This works even for databases that do not allow reuse of deleted records. Once the transaction is backed out, the contents of the transaction file are discarded. If you terminate your program with a transaction in progress, an automatic transaction abort will occur.
Since we are writing to a "virtual transaction file," the file will use extended and/or expanded memory, with only the overflow actually being written to disk. Since the transaction file will never contain more than one transaction's data, it is most likely that memory will not be overflowed and no actual disk I/O will ever occur.
What Client-Atomic Transaction Processing Won't Do
First, client-atomic transaction processing does not protect a database from a crash. This means that if a transaction was in progress and the system crashes (maybe because of a power failure) or your program terminates abnormally, the transaction will be partially completed. You would then have to either manually fix up the data or restore the data from backup.
There is also no protection from I/O errors. If you get an I/O error during a database operation that is part of a transaction, you can attempt to abort the transaction. However, there is no guarantee that the abort will work correctly. It is also possible to get an error during the abort process itself. In either case, abort_transaction would return an error, and you would probably want to restore the data from backup.
As discussed earlier, a lock is in effect during a transaction. While this prevents other processes from writing to the tables, it does not prevent them from reading. This means that, just as when not using transaction processing, another process can read a partially complete transaction.