Multics Technical Bulletin MTB-555 DM: Transaction Manager Spec Revision 1 To: Distribution From: Steve Herbst, Matt Pierret Date: 03/26/84 Subject: Data Management: Transaction Manager Functional Spec ABSTRACT This MTB talks about the transaction manager, the part of the Data Management System (DMS) Integrity Services that is responsible for coordinating transactions in user processes. The MTB describes the entry points in transaction_manager_ and the operations they perform on transactions, the role of the system-wide Transaction Definition Table (TDT), and the DMS's responsibilities regarding transactions. Comments should be sent to the author: via Multics Mail: Herbst.Multics on either MIT Multics or System M. via US Mail: Steve Herbst Honeywell Information Systems 4 Cambridge Center Cambridge, Massachusetts 02142 via telephone: (HVN) 261-9319, or (617) 492-9319 _________________________________________________________________ Multics project internal working documentation. Not to be reproduced or distributed outside the Multics project without the consent of the author or the author's management. CONTENTS Page Abstract . . . . . . . . . . . . . . . i 1 Introduction . . . . . . . . . . . . 1 2 Transaction operations . . . . . . . 2 3 Process termination . . . . . . . . 3 4 DMS adoption . . . . . . . . . . . . 3 5 Error recovery . . . . . . . . . . . 3 6 Transaction Definition Table (TDT) . 3 7 Initialization errors . . . . . . . 4 8 Description of the entry points . . 5 transaction_manager_ . . . . . . . 5 $begin_txn . . . . . . . . . . . 6 $commit_txn . . . . . . . . . . 8 $abort_txn . . . . . . . . . . . 10 $rollback_txn . . . . . . . . . 12 $handle_conditions . . . . . . . 14 $suspend_txn . . . . . . . . . . 15 $resume_txn . . . . . . . . . . 16 $abandon_txn . . . . . . . . . . 17 $adjust_txn . . . . . . . . . . 18 $kill_txn . . . . . . . . . . . 19 $get_current_txn_id . . . . . . 20 $get_txn_info . . . . . . . . . 21 txn_info structure . . . . . . . 22 $get_txn_info_index . . . . . . 25 $get_state_description . . . . . 26 $get_tdt_size . . . . . . . . . 27 $get_tdt_index . . . . . . . . . 28 $adjust_tdt_entry . . . . . . . 29 $adjust_process_id . . . . . . . 30 $adjust_tdt . . . . . . . . . . 31 $per_system_init . . . . . . . . 32 $per_process_init . . . . . . . 33 $user_shutdown . . . . . . . . . 34 shutdown_info structure . . . . 34 $begins_off . . . . . . . . . . 36 $begins_on . . . . . . . . . . . 37 $recover_after_crash . . . . . . 38 . Multics Technical Bulletin MTB-555 DM: Transaction Manager Spec 1 INTRODUCTION A Data Management (DM) transaction begins when the user calls transaction_manager_$begin_txn and ends when the user calls either $commit_txn or $abort_txn. Operations to protected files while the transaction is in progress form a logically inseparable unit: They are all made permanent by $commit_txn or completely undone by $abort_txn. Transactions protect only the contents of protected DM files (see MTB-553, "File Manager Specifications"). They do not protect non-DM data such as MRDS cursors or opening information, or data in unprotected DM files. The most general implementation for a transaction manager would place no restrictions on the relationships among transactions and processes. In such a model: - More than 1 transaction could be in progress at the same time in the same process. - More than 1 process could be operating at a given time on the same transaction. - Any transaction could spawn any number of other transactions. - Any process could spawn any number of other processes. In the MR11 implementation, however, the model has been restricted to its simplest form: - No more than 1 transaction can be in progress at a given time in the same process. - No more than 1 process can be operating at a given time on the same transaction. - A transaction cannot spawn another transaction. - A process cannot spawn another process. Some of these restrictions may be removed in the future. The Data Management System (DMS) has a daemon process, Data_Management.Daemon, that is always logged in. This daemon process is responsible for aborting transactions belonging to processes that have died or have relinquished control of ("abandoned", see below) transactions that they cannot complete. Some of the transaction_manager_ entry points documented in this MTB perform privileged operations and can only be called by Data_Management.Daemon. The transaction manager operates by calling the other managers that comprise the DMS Integrity Services. These are the before journal manager (MTB-559), which records database changes in its journals so that they can be rolled back, the file manager (MTB-553), which makes permanent the changes to indvidual control MTB-555 Multics Technical Bulletin DM: Transaction Manager Spec intervals, and the lock manager (MTB-557), which handles concurrent access to files. 2 TRANSACTION OPERATIONS When a process successfully executes $begin_txn, a transaction comes into existence and becomes the "current transaction" of the process. As stated above, there can be only one current transaction at a time per process. The process is referred to as the "owner" of the transaction. The owner of a transaction can perform the following operations on it: 1. COMMIT: A successful call to $commit_txn terminates the transaction, making all changes permanent, and allows the process to begin another transaction. 2. ABORT: A successful call to $abort_txn terminates the transaction, undoing all changes, and allows the process to begin a new transaction. 3. ROLLBACK: A successful call to $rollback_txn undoes all changes but leaves the transaction still in progress. 4. SUSPEND: After $suspend_txn returns successfully, the transaction is in the "suspended" state until a call to $resume_txn. The process still owns the transaction and cannot begin a new one. However, data operations to protected files are not allowed while the transaction is suspended. This mechanism is used for handling interruptions such as QUIT's, faults, alarms, and interactive messages. By suspending the ongoing transaction until the interruption is over, the user protects the transaction's databases from being damaged by the interruption. 5. RESUME: A successful call to $resume_txn reverts the suspended state. 6. ABANDON: A successful call to $abandon_txn relinquishes ownership of the transaction, making it an "orphan". Data_Management.Daemon then becomes responsible for "adopting" the orphan transaction (temporarily pretending to be its owner) and aborting it. The process that abandoned the transaction is meanwhile free to begin another one. A process usually abandons a transaction if it is unable to either commit it or abort it due to uncorrectable errors. Abandoning a transaction does not compromise the integrity Multics Technical Bulletin MTB-555 DM: Transaction Manager Spec of the data files, since Data_Management.Daemon will roll back any modifications if necessary. 7. KILL: This is a dangerous and rare operation, used only when the consistency of the transaction's databases is no longer an issue (for example, if they are to be deleted), to save Data_Management.Daemon an expensive abort in cases where many changes have been made to the data. A successful call to $kill_txn makes the transaction an orphan to be deleted by Data_Management.Daemon WITHOUT an abort. 3 PROCESS TERMINATION If a process terminates while owning a transaction, the transaction automatically becomes an orphan. It is then adopted and aborted by Data_Management.Daemon as if it had been explicitly abandoned. 4 DMS ADOPTION When Data_Management.Daemon adopts a transaction that has been abandoned or whose owner is no longer running, it does not usually attempt to continue what the owner was doing. Only in the case where an interrupted commit has gotten far enough so that it is a simple matter to finish it, is the transaction committed. In all other cases, the transaction is aborted and all database changes are rolled back. If Data_Management.Daemon itself is unable to abort the transaction due to an error, it sends mail to the original owner. The owner can either help complete the transaction or make the decision to call $kill_txn. 5 ERROR RECOVERY When an error is encountered by $commit_txn, $abort_txn, or $rollback_txn, the transaction is left in an "error state". There are several ways that an error transaction can be fixed. If the user process can correct the problem, it can then repeat the same operation that got an error and hope that it runs to completion. If the user cannot correct the problem, the available choices are to abandon or kill the transaction. Only in the case of $kill_txn can database consistency be lost. MTB-555 Multics Technical Bulletin DM: Transaction Manager Spec 6 TRANSACTION DEFINITION TABLE (TDT) The system-wide TDT contains information that is not critical to maintaining consistency of Data Management files but is used to coordinate operations on transactions. The TDT contains an entry for each in-progress transaction on the system. The entry for a transaction is logically divided into several parts, each part managed solely by one of the Data Management System components: transaction manager, file manager, before journal manager, and lock manager. All components use the same array index for a particular transaction. The transaction manager is the authority on looking up a transaction in the table. The transaction manager portion of the TDT entry includes the following information: (1) Transaction identifier. (2) Mode, e.g. "normal", "test", etc. (3) State, e.g. "in-progress", "step N in commit", etc. (4) Error information. (5) Date-time the transaction began. (6) Process identifier and Person.Project of the creator. (7) Flags: abandoned, suspended, owner-is-dead, etc. The transaction manager also remembers the current transaction for each process. A process can find out its current transaction by calling $get_current_txn_id, which also says if the transaction is suspended or in error. Additional information can be obtained from $get_txn_info. | 7 INITIALIZATION ERRORS | The first time any DMS (eg., transaction_manager_) call is | made in a process, a first-reference trap performs initialization | of needed variables such as a pointer to the TDT. Errors that | occur during initialization itself are reported by means of | sub_err_. Callers of DMS entry points, for example the | transaction command, are therefore expected to handle the | sub_error_ condition. The particular error code | dm_error_$system_not_initialized reported by sub_err_ indicates | that the DMS is currently not available to the system as a whole | (for example, because Data_Management.Daemon has not yet | completed its systemwide initialization). 8 DESCRIPTION OF THE ENTRY POINTS ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Name: transaction_manager_ Entry points in transaction_manager_ begin and end transactions on behalf of users, return information about transactions, and recover transactions after system failure. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$begin_txn This entry point begins a transaction on behalf of the | caller. If a transaction is already in progress or suspended in the calling process, this entry returns the code | dm_error_$transaction_in_progress or | dm_error_$transaction_suspended. Otherwise, it generates a unique transaction identifier, passes it to the before journal manager to begin a transaction, records the transaction identifier as the current transaction for the process, and places it in a TDT entry along with other information about the transaction such as its state (in-progress) and the owner's name. Usage dcl transaction_manager_$begin_txn entry (fixed bin (17), bit (36), bit (36) aligned, fixed bin (35)); call transaction_manager_$begin_txn (mode, before_journal_opening_id, txn_id, code); where: mode (Input) is the mode determining which of several protocols to use. The available modes are declared in the include file dm_tm_modes.incl.pl1: TM_NORMAL_MODE: requires locks to accompany all gets and puts, and requires all updates to be journalized. TM_STATISTICAL_MODE: requires no locking or journalization; unprotected reads are allowed but protected files cannot be updated. TM_READ_ONLY_MODE: requires locks to accompany all gets, but puts to protected files are not allowed. Therefore, no journalization is needed. Protected files cannot be created or deleted. TM_NEVER_WRITE_MODE: requires locks to accompanmy all gets, but puts, even to unprotected files, are not allowed. Therefore, no journalization is needed. Protected and unprotected files cannot be created or deleted. This mode is useful primarily for debugging. TM_TEST_NORMAL_MODE: acts like NORMAL mode, but any attempt to commit the transaction is converted silently into an abort. Therefore, no files are ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ changed. Test normal mode can be used to test transactions that are to be run in normal mode. TM_TEST_STATISTICAL_MODE: acts like STATISTICAL mode, but commit is converted into abort. TM_TEST_READ_ONLY_MODE: acts like READ_ONLY mode, but commit is converted into abort. TM_TEST_NEVER_WRITE_MODE: acts like never-write mode, but commit is converted into abort. before_journal_opening_id (Input) is the opening identifier of the before journal to be used by this transaction. If zero, a before journal is assigned by default to this transaction. txn_id (Output) is the identifier of the newly-created transaction. It is generated by transaction_manager_$begin_txn and is guaranteed to be unique across all Multics systems. Transaction identifiers are not reusable. code (Output) is a standard system status code, including the dm_error_ codes: $invalid_mode | The specified mode is not currently | supported. | $no_begins | Transactions are not allowed to be begun | because Data_Management.Daemon has called | transaction_manager_$begins_off, for example | when preparing to do a systemwide DMS | shutdown. | $transaction_suspended A transaction cannot be begun because a suspended one already exists. $transaction_in_progress A transaction cannot be begun because one is already active. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$commit_txn This entry point commits the current transaction. Any modifications made to files since the transaction began become permanent and visible to other transactions, as if all the changes were made in the same instant. This is done according to the following sequence: (1) Call the before journal manager to flush (force write to secondary storage) before images produced by this transaction. (2) Call the file manager to flush data base control intervals modified by this transaction. (3) Wait for completion of I/O's generated in steps 1-2. (4) Write transaction-committed mark. (5) Call the lock manager to unlock all locks held by the transaction. (6) Zero the transaction in the TDT and zero the current transaction information. Usage dcl transaction_manager_$commit_txn entry (bit (36) aligned, fixed bin (35)); call transaction_manager_$commit_txn (txn_id, code); where: txn_id (Input) is the transaction identifier of the current transaction, or "0"b to default to the current transaction. If txn_id is neither "0"b nor the transaction identifier of the current transaction, dm_error_$transaction_not_current is returned. This argument can be used as a check to be sure which transaction is being committed. code (Output) is a standard system status code, including the dm_error_ codes: $no_current_transaction No current transaction is defined for this process. $not_own_transaction A process can only commit its own transaction. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ $transaction_suspended | The current transaction is suspended and | therefore cannot be committed. | $unfinished_abort The transaction was left in the middle of an abort operation. It is possible to call $abort_txn to complete the abort, or call either $abandon_txn or $kill_txn. $unfinished_rollback The transaction was left in the middle of a rollback operation. It is possible to call $rollback_txn to complete the rollback, call $abort_txn to abort the transaction, or call either $abandon_txn or $kill_txn. Notes | This entry point will retry commit of a transaction that was left | in an error state by a previous commit. It will not, however, | touch a transaction left in error by any other operation. | ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$abort_txn This entry point aborts the current transaction, returning all modified files to the state they were in before the transaction began. This is done according to the following sequence: (1) Call the before journal manager to flush before images produced by this transaction. (2) Call the before journal manager to roll back the transaction by replacing all its before images in the file. (3) Call the file manager to flush data base control intervals modified by the transaction. (4) Call the before journal manager to write an aborted mark. (5) Call the lock manager to unlock all locks held by the transaction. (6) Zero the transaction in the TDT and zero the current transaction information. Usage dcl transaction_manager_$abort_txn entry (bit (36) aligned, fixed bin (35)); call transaction_manager_$abort_txn (txn_id, code); where: txn_id (Input) is the transaction identifier of the current transaction, or "0"b to default to the current transaction. If txn_id is neither "0"b nor the transaction identifier of the current transaction, dm_error_$transaction_not_current is returned. This argument can be used as a check to be sure which transaction is being aborted. code (Output) is a standard system status code, including the dm_error_ codes: $no_current_transaction No current transaction is defined for this process. $not_own_transaction A process can only abort its own transaction. | $transaction_suspended | The current transaction is suspended and ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ therefore cannot be aborted. | $unfinished_commit The transaction was left in the middle of a commit operation. It is possible to call $commit_txn to complete the commit, or call either $abandon_txn or $kill_txn. Notes | If the transaction has already been abandoned, this entry point | causes Data_Management.Daemon to abort it immediately. | This entry point will retry abort of a transaction that was left | in an error state by a previous abort or rollback. It will not | touch a transaction left in error by any other operation. | ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$rollback_txn This entry point is intended eventually to provide a rollback-to-checkpoint capability. With a future implementation, the user will be able to work in stages, checkpointing when each stage is correct, but not committing (and therefore making the changes visible to other users) until all stages of the transaction are complete. Since checkpoints are not implemented for MR10, it is currently only possible to roll back to the start of the transaction. Rollback is done according to the following sequence: (1) Call the before journal manager to flush before images produced by the transaction. (2) Call the before journal manager to roll back the transaction by replacing all the before images in the file. (3) Call the file manager to flush data base control intervals modified by this transaction. (4) Call the before journal manager to write a rolled-back mark. (5) Call the lock manager to unlock all locks held by the transaction. (6) Set the state of the transaction back to in-progress. Usage dcl transaction_manager_$rollback_txn entry (bit (36) aligned, fixed bin, fixed bin (35)); call transaction_manager_$rollback_txn (txn_id, checkpoint_number, code); where: txn_id (Input) is the transaction identifier of the current transaction, or "0"b to default to the current transaction. If txn_id is neither "0"b nor the transaction identifier of the current transaction, dm_error_$transaction_not_current is returned. This argument can be used as a check to be sure which transaction is being rolled back. checkpoint_number (Input) must currently be 0. code (Output) ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ is a standard system status code, including the dm_error_ codes: $no_current_transaction No current transaction is defined for this process. $not_own_transaction A process can only roll back its own transaction. $transaction_suspended | The current transaction is suspended and | therefore cannot be rolled back. | $unfinished_abort The transaction was left in the middle of an abort operation. It is possible to call $abort_txn to complete the abort, or call either $abandon_txn or $kill_txn. $unfinished_commit The transaction was left in the middle of a commit operation. It is possible to call $commit_txn to complete the commit, or call either $abandon_txn or $kill_txn. Notes | This entry point will retry rollback of a transaction that was | left in an error state by a previous rollback. It will not touch | a transaction left in error by any other operation. | ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ | Entry: transaction_manager_$handle_conditions | This entry point, intended to be called by "any_other" | handlers in user programs, temporarily suspends the current | transaction during an interruption caused by a signalled | condition. When invoked, it suspends the current transaction, | allows the condition to propagate, and resumes the transaction | when control returns. | Usage | dcl transaction_manager_$handle_conditions entry (); | call transaction_manager_$handle_conditions (); ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$suspend_txn This entry point puts the current transaction into a suspended state wherein it is temporarily unusable. Data operations to protected files are not allowed while the transaction is suspended, that is, until $resume_txn is called. Since the suspended transaction has not been completed, no new transaction can be begun. Usage dcl transaction_manager_$suspend_txn entry (fixed bin (35)); call transaction_manager_$suspend_txn (code); where: code (Output) is a standard system status code, including the dm_error_ codes: $no_current_transaction No current transaction is defined for this process. $transactions_out_of_sequence The current transaction is already suspended. Notes Suspension has the following effects: 1. The current transaction is temporarily unusable. As a result, the entry point $get_current_txn_id returns "0"b and the error code dm_error_$transaction_suspended. 2. No data operations on protected files are allowed while the transaction is suspended. 3. Both $begin_txn and $commit_txn return dm_error_$transaction_suspended. 4. Both $abort_txn and $adjust_tdt_entry (called by DMS) work on suspended transactions. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$resume_txn This entry point reactivates the current transaction, once again allowing data operations on protected files. Usage dcl transaction_manager_$resume_txn entry (fixed bin (35)); call transaction_manager_$resume_txn (code); where: code (Output) is a standard system status code, including the dm_error_ codes: $no_current_transaction No current transaction is defined for this process. $no_suspended_transaction The current transaction is not suspended. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$abandon_txn This entry point relinquishes control of a user's transaction, causing it to be picked up and adjusted (aborted unless a commit was already in progress) by Data_Management.Daemon. The caller is immediately given a new TDT entry and can begin another transaction. Usage dcl transaction_manager_$abandon_txn entry (bit (36) | aligned, fixed bin (35)); | call transaction_manager_$abandon_txn (txn_id, code); | where: | txn_id (Input) | is the transaction identifier of the current | transaction, or "0"b to default to the current | transaction. If txn_id is neither "0"b nor the | transaction identifier of the current transaction, | dm_error_$transaction_not_current is returned. This | argument can be used as a check to be sure which | transaction is being abandoned. | code (Output) is a standard system status code, including the dm_error_ codes: $no_current_transaction No current transaction is defined for this process. $not_own_transaction A process can only abandon its own transaction. $transaction_suspended | The current transaction is suspended and | therefore cannot be abandoned. | ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ | Entry: transaction_manager_$adjust_txn | This entry point is called by the owner of a transaction to | ask Data_Management.Daemon to try again to adjust the | transaction. The transaction must be in the abandoned state. A | user who has received mail of the form "Failed to adjust | transaction..." can fix the problem, if possible, and then call | this entry point. | Usage | dcl transaction_manager_$adjust_txn entry (bit (36) aligned, | fixed bin (35)); | call transaction_manager_$adjust_txn (txn_id, code); | where: | txn_id (Input) | is the transaction identifier of the transaction to | be adjusted. | code (Output) | is a standard system status code. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$kill_txn This dangerous entry point is intended to be called by the owner of a transaction ONLY when the owner cannot end the transaction normally and does not want the daemon to try to abort it for reasons of efficiency. Killing a transaction can destroy the consistency of the databases changed during the transaction, and is therefore appropriate only if consistency is no longer an issue (for example, if the databases are to be deleted). As with $abandon_txn, calling this entrypoint frees the user to begin a new transaction. Usage dcl transaction_manager_$kill_txn entry (bit (36) aligned, | fixed bin (35)); | call transaction_manager_$kill_txn (txn_id, code); | where: txn_id (Input) is the transaction identifier of the transaction to be killed. If it is "0"b, the current transaction is | assumed. | code (Output) | is a standard system status code, including the | dm_error_ codes: | $no_current_transaction | With txn_id="0"b, no current transaction is | defined for this process. | $transaction_suspended | With txn_id="0"b, the current transaction is | suspended and therefore cannot be killed. | Access required The caller requires "re" access to dm_admin_gate_. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$get_current_txn_id This entry point returns the transaction identifier of the current transaction, even if it is suspended or in error. See "Notes" below for a table of transaction identifiers and error codes returned. Usage dcl transaction_manager_$get_current_txn_id entry (bit (36) aligned, fixed bin (35)); call transaction_manager_$get_current_txn_id (txn_id, code); where: txn_id (Output) is the identifier of the current transaction. code (Output) is one of the codes listed below. Notes The txn_id and code values returned depend on the status of the current transaction: txn_id code ------ ---- 1. Txn in progress. valid id 0 2. No current txn. 0 dm_error_$no_current_transaction 3. Txn suspended. valid id dm_error_$transaction_suspended 4. Txn in error. valid id dm_error_$unfinished_abort or: dm_error_$unfinished_commit or: dm_error_$unfinished_rollback ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$get_txn_info This entry point returns a structure containing all the information in the TDT about a transaction. This structure, shown below, is declared in dm_tm_txn_info.incl.pl1. Usage dcl transaction_manager_$get_txn_info entry (bit (36) aligned, ptr, fixed bin (35)); call transaction_manager_$get_txn_info (txn_id, txn_info_ptr, code); where: txn_id (Input) is the transaction identifier of a transaction, or "0"b to default to the current transaction. txn_info_ptr (Input) is a pointer to the txn_info structure. code (Output) is a standard system status code. Access required The caller requires "re" access to dm_admin_gate_ to obtain information about another user's transaction. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ txn_info structure dcl 1 txn_info aligned based (txn_info_ptr), 2 version char (8), 2 txn_id bit (36) aligned, 2 txn_index fixed bin, 2 mode fixed bin, 2 state fixed bin, 2 error_code fixed bin (35), | 2 checkpoint_id fixed bin, | 2 rollback_count fixed bin, 2 owner_process_id bit (36), 2 owner_name char (32), 2 date_time_created fixed bin (71), 2 flags, 3 (dead_process_sw, suspended_sw, error_sw, abandoned_sw, kill_sw) bit (1) unaligned, 3 mbz bit (31) unaligned, | 2 journal_info aligned, | 3 bj_uid bit (36), | 3 last_completed_operation char (4), | 3 first_bj_rec_id bit (36), | 3 last_bj_rec_id bit (36), | 3 n_rec_written fixed bin (35), | 3 n_bytes_written fixed bin (35); where: version | is the version of the structure, TXN_INFO_VERSION_4. txn_id is the transaction identifier of the transaction. txn_index is the index of the TDT entry for the transaction. mode is the mode according to which the transaction was begun. See $begin_txn for a list of modes. state is one of the states declared in the include file dm_tm_states.incl.pl1. It is either ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ TM_IN_PROGRESS_STATE for an in-progress transaction, one of several intermediate states corresponding to calls made by the transaction manager (usually when the owner process has died in the middle of a call to transaction_manager_), or one of several error states corresponding to error codes returned by transaction_manager_. error_code is 0 or an error code returned by the last call made by the transaction manager. checkpoint_id | is the identifier of the checkpoint that has most | recently been rolled back to, or 0 for the start of | the transaction. | rollback_count | is the number of times that the transaction has been | rolled back, either by a rollback operation or as | part of an unfinished abort. | owner_process_id is the process_id of the process that began the transaction. This process may or may not still be running. owner_name is the Person.Project identifier of the process that began the transaction. date_time_created is the date-time that the transaction was begun. dead_process_sw is "1"b if the process that began the transaction is no longer running. suspended_sw is "1"b if the transaction is currently suspended. error_sw is "1"b if the transaction manager got an error code back from one of its calls (error_code ^= 0) and the transaction has not been adjusted since. abandoned_sw is "1"b if the transaction was abandoned by the owner via a call to $abandon_txn. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ kill_sw is "1"b if the owner called $kill_txn and the transaction is therefore waiting to be killed. | bj_uid | is the UID of the before journal chosen when the | transaction was begun. | last_completed_operation | is the name of the last completed before journal | operation. | first_bj_rec_id | is the id of the first mark for this transaction. | last_bj_rec_id | is the identifier of the last mark for this | transaction. | n_rec_written | is the number of marks that were written for this | transaction. | n_bytes_written | is the total number of bytes written to the journal. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$get_txn_info_index | This entry point returns the same information as | transaction_manager_$get_txn_info but accepts the index of a TDT | entry rather than a transaction identifier. The transaction | command, for example, calls this entry point with numbers 1 | through transaction_manager_$get_tdt_size() to print information | for the entire TDT. | Usage | dcl transaction_manager_$get_txn_info_index entry (fixed | bin, ptr, fixed bin (35)); | call transaction_manager_$get_txn_info_index (txn_index, | txn_info_ptr, code); | where: | txn_index (Input) | is the index of a TDT entry. | txn_info_ptr (Input) | is a pointer to the txn_info structure. | code (Output) | is a standard system status code. | Access required | The caller requires "re" access to dm_admin_gate_ to obtain | information about another user's transaction. | ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ | Entry: transaction_manager_$get_state_description | This entry point generates a character string description of | a numerical state returned by transaction_manager_$get_txn_info | or transaction_manager_$get_txn_info_index. | Usage | dcl transaction_manager_$get_state_description entry | (fixed bin) returns (char (*)); | state_description = | transaction_manager_$get_state_description (state); ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$get_tdt_size | This entry point returns the number of entries allocated to | the entire TDT. In other words, it returns the index of the last | possible TDT entry. This number can be used as an upper bound to | loop through the TDT, calling | transaction_manager_$get_txn_info_index for each entry. | Usage | dcl transaction_manager_$get_tdt_size entry () returns | (fixed bin); | max_tdt_index = transaction_manager_$get_tdt_size (); | ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ | Entry: transaction_manager_$get_tdt_index | This entry point returns the index of the TDT entry occupied | by a specified transaction. | Usage | dcl transaction_manager_$get_tdt_index entry (bit (36) | aligned, fixed bin (35)) returns (fixed bin); | txn_index = transaction_manager_$get_tdt_index (txn_id, | code); | where: | txn_id (Input) | is the transaction identifier of a transaction. The | identifier of the current transaction can be obtained | from transaction_manager_$get_current_txn_id. | code (Output) | is a standard system status code, including the | dm_error_ code: | $transaction_not_found | No transaction exists with the specified | transaction identifier. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$adjust_tdt_entry This entry point, callable only by Data_Management.Daemon, frees a specified TDT entry. If the TDT entry is occupied by a transaction, this transaction is first adjusted by either aborting it, if it is in-progress, or finishing any operation such as commit or abort that was previously interrupted due to an error. The DMS normally calls this entry point: 1. When requested by a user process executing $per_process_init that finds a transaction in the TDT belonging to a dead process. 2. When requested by $abandon_txn in a user process. The TDT entry to be freed must be abandoned ($abandon_txn), belong to a dead process, or contain a transaction that is to be killed ($kill_txn). If the adjustment encounters an error, further action depends on whether the transaction is to be killed. If so, the TDT entry is simply deleted, thereby losing all recovery information. If the transaction is not to be killed, Data_Management.Daemon sends mail to the transaction's owner describing the error and leaves the TDT entry intact. Usage dcl transaction_manager_$adjust_tdt_entry entry (bit (36) aligned, fixed bin, fixed bin (35)); call transaction_manager_$adjust_tdt_entry (txn_id, txn_index, code); where: txn_id (Input) must equal the transaction identifier of the transaction, if any, occupying the TDT entry specified by txn_index. txn_index (Input) is the number of the TDT entry to be adjusted. code (Output) is a standard system status code, including $tdt_entry_in_use: The entry cannot be adjusted because the owner process is still running, and the transaction has not been abandoned. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ | Entry: transaction_manager_$adjust_process_id | This entry point, callable only by Data_Management.Daemon, | adjusts the transaction belonging to a specified process. | Adjustment is similar to that performed by | transaction_manager_$adjust_tdt_entry. | Usage | dcl transaction_manager_$adjust_process_id entry (bit (36) | aligned, fixed (35)); | call transaction_manager_$adjust_process_id (process_id, | code); | where: | process_id (Input) | is a process identifier. | code (Output) | is a standard system status code, including the | dm_error_ code: | $process_not_found | There is no such process. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$adjust_tdt | This entry point, callable only by Data_Management.Daemon, | adjusts all TDT entries belonging to dead processes. Adjustment | is similar to that performed by | transaction_manager_$adjust_tdt_entry. | Usage | dcl transaction_manager_$adjust_tdt entry (); | call transaction_manager_$adjust_tdt (); | ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$per_system_init This entry point, called by the Initializer process when bringing up Data Management in a new bootload, creates and initializes the TDT. Usage dcl transaction_manager_$per_system_init entry (fixed bin (35)); call transaction_manager_$per_system_init (code); where: code (Output) is a standard system status code, nonzero if the TDT could not be allocated. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$per_process_init This entry point, called automatically by the user process the first time it invokes any part of the Data Management System, reserves a TDT slot for the process. If while doing so it notices a TDT entry belonging to a dead process, it sends a request to Data_Management.Daemon asking it to call $adjust_tdt_entry on that entry. Usage dcl transaction_manager_$per_process_init entry (fixed bin (35)); call transaction_manager_$per_process_init (code); where: code (Output) is zero or dm_error_$tdt_full if there is no more room left in the TDT. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ | Entry: transaction_manager_$user_shutdown | This entry point turns off the DMS for a particular process. | This is done according to the following sequence: | (1) If the caller process is not currently using the DMS, | return. | (2) Adjust all TDT entries belonging to the caller's | Person.Project. | (3) Call dm_util_$terminate_dm to turn off the DMS for the | caller process. | Information about the adjusted TDT entries is returned in the | structure shutdown_info, declared in | dm_tm_shutdown_info.incl.pl1. | Usage | dcl transaction_manager_$user_shutdown entry (ptr, ptr, | fixed bin (35)); | call transaction_manager_$user_shutdown (area_ptr, | shutdown_info_ptr, code); | where: | area_ptr (Input) | is a pointer to an area in which to allocate the | shutdown_info structure. | shutdown_info_ptr (Output) | is the returned pointer to shutdown_info, described | below. | code (Output) | is a standard system status code. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ shutdown_info structure | dcl 1 shutdown_info aligned based (shutdown_info_ptr), | 2 version char (8), | 2 count fixed bin, | 2 transaction (shutdown_alloc_count refer | (shutdown_info.count)), | 3 txn_id bit (36) aligned, | 3 op_completed fixed bin, | 3 state fixed bin, | 3 error_code fixed bin (35); | where: | version | is the version of the structure, | SHUTDOWN_INFO_VERSION_1. | count | is the number of transactions that were adjusted. | txn_id | is the identifier of a transaction that was adjusted. | op_completed | is equal to one of the constants ABORTED, | FINISHED_ABORT, or FINISHED_COMMIT, declared in the | same include file. | state | is the state after adjusting, 0 for a successful | adjustment. | error_code | is the error code returned by adjust, 0 for a | successful adjustment. | ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ | Entry: transaction_manager_$begins_off | This entry point prevents any further transactions from | being begun by user processes, until | transaction_manager_$begins_on is called. The default is "begins | on". Data_Management.Daemon calls this entry point, for example, | early in the system DMS shutdown procedure to give it time to | quiesce the system before disabling the DMS. | Usage | dcl transaction_manager_$begins_off entry (); | call transaction_manager_$begins_off (); | Access required | The caller requires "re" access to dm_daemon_gate_. ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$begins_on | This entry point reverts the effect of | transaction_manager_$begins_off. | Usage | dcl transaction_manager_$begins_on entry (); | call transaction_manager_$begins_on (); | Access required | The caller requires "re" access to dm_daemon_gate_. | ____________________ ____________________ transaction_manager_ transaction_manager_ ____________________ ____________________ Entry: transaction_manager_$recover_after_crash This entry point, called only by Data_Management.Daemon when bringing up the DM system after a crash, adjusts all unfinished transactions that existed at the time of the crash. It is given pointers to two tables, created by the before journal manager from its journal, containing an entry for each unfinished transaction. It builds a temporary TDT containing these transactions and calls $adjust_tdt_entry on each entry. Usage dcl transaction_manager_$recover_after_crash entry (ptr, ptr, fixed bin (35)); call transaction_manager_$recover_after_crash (struc1_ptr, struc2_ptr, code); where: struc1_ptr (Input) is a pointer to a table built by the before journal manager. struc2_ptr (Input) is a pointer to a table built by the before journal manager. code (Output) is a standard system status code.