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.