Previous Topic

Next Topic

Begin

Mark beginning of transaction.

Short Name

TRANBEG()

Type

Low-level data file function

Declaration

  LONG Begin(COUNT trnmod)

Description

Begin() marks the beginning of a transaction. All files opened by this user, that have been created with a file mode of either ctPREIMG or ctTRNLOG, will have file updates held until they are committed with a matching call to Commit(). For a full description of transaction processing, see the chapter on Data Integrity in the c-tree Plus Programmer’s Reference Guide.

trnmod values presently supported are summarized in the following table:

trmmod value

Operation

ctTRNLOG

Full transaction processing functionality, including auto-recovery. Mutually exclusive to ctPREIMG.

ctPREIMG

Transaction atomicity only, auto-recovery is not available. Mutually exclusive to ctTRNLOG.

ctENABLE

Automatically implements LockISAM(ctENABLE) when applicable. Mutually exclusive with ctREADREC.

ctREADREC

Automatically implements LockISAM(ctREADREC) when applicable. Mutually exclusive with ctENABLE.

ctLK_BLOCK

Automatically implements blocking locks when OR-ed with ctREADREC or ctENABLE.

ctLK_RECR

Enables recursive locking.

ctSAVENV

Saves current ISAM position after each successful ISAM file update operation (i.e., ReWriteRecord(), DeleteRecord(), etc. ).

ctAUTOSAVE

Automatically invokes savepoints after each successful ISAM or resource update. Disables ctSAVENV.

ctCOMMIT_SWAP

Automatic Commit operation on memory swap (Server only).

Either ctPREIMG or ctTRNLOG must be used to specify the transaction logging mode.

Note: Using ctPREIMG with a file created with ctTRNLOG results in a TTYP_ERR (99).

Either ctENABLE or ctREADREC may also be OR-ed in to automatically invoke LockISAM(). If either is used, ctLK_BLOCK can be OR-ed in to convert the locks to blocking locks. This sleeps the process until the lock is available instead of returning DLOK_ERR (42).

If ctSAVENV is used, or if the user profile in InitCTreeXtd() or InitISAMXtd() includes USERPRF_SAVENV, then the current ISAM position of the files updated during the transaction is saved. This allows a subsequent Abort() or RestoreSavePoint() to reset the current ISAM position of the files.

Automatic Savepoints

ctAUTOSAVE automatically follows each successful ISAM update or resource update with a special savepoint. The savepoint permits an update error to be rolled-back so that a compound transaction can continue its updates and subsequently Commit() the transaction. This automatic savepoint does NOT support the ctSAVENV profile setting. ctSAVENV is disabled if ctAUTOSAVE is on.

This approach is faster than explicit savepoints after each update since no network traffic is required between updates, and the auto savepoint is more efficient than an explicit savepoint.

If an error occurs in the middle of a set of updates within a single transaction, and if ctAUTOSAVE was in trnmod, the application simply calls RestoreSavePoint(-1) to roll-back the error, and continues update processing.

Explicit calls to SetSavePoint() should not be made when ctAUTOSAVE is effective. Error ASAV_ERR (532) will be returned by SetSavePoint() if called after updates have occurred. A typical usage pattern in pseudo-code would be:

Begin(ctTRNLOG | ctAUTOSAVE | ctENABLE)
    loop: update operation
          if error
              RestoreSavePoint(-1)
          if not done
              goto loop
Commit(...)

Deferred Begin

It is not uncommon for a higher-level API to start transactions without knowledge of whether or not any updates will occur. To reduce the overhead of unnecessary log flushes, a deferred mode is available. ctDEFERBEG results in the actual TRANBEG entry in the log to be delayed until an attempt is made to update a transaction controlled file, and if a TRANEND() or TRANABT() is called without any updates, then the transaction begin and end log entries are not flushed to disk. ctDEFERBEG has no affect for ctPREIMG transactions.

Note: When using a transaction mode of deferred begin, Begin(ctTRNLOG | ctDEFERBEG) returns a value of 1 as the actual transaction number assignment is delayed until the log write of the first file update takes place.

Automatic commit on memory swapping (Server Only)

ctCOMMIT_SWAP causes an automatic Commit(ctKEEP_OUT), followed by a Begin(), when memory swapping begins. Memory swapping is caused by exceeding a limit on user memory or guest memory which sets the user OPS_MEMORY_SWP status bit, (see the SetOperationState() function description for the definition of the status bits). ctCOMMIT_SWAP can be OR-ed in with other modes, such as ctAUTOSAVE, and causes the OPS_COMMIT_SWP bit to be set when a transaction is automatically committed (and restarted) because of a memory limit which causes pre-image space swapping.

Unlike the OPS_MEMORY_SWP bit, which is automatically reset on a Begin() call, the OPS_COMMIT_SWP bit must be cleared by the application using SetOperationState(OPS_COMMIT_SWP,OPS_STATE_OFF)). The intent is that inside a loop in which repeated updates are made, the OPS_COMMIT_SWP bit will be tested. If set, the application knows that the original large transaction has been broken down into smaller pieces and it knows where this break occurred. By immediately resetting the bit, the test can be continually made within the loop, as displayed in the following pseudo code example:

counter = 0;
Begin(ctENABLE_BLK | ctCOMMIT_SWAP);
do {
  get data;
  update data;
  ++counter;
  if (SetOperationState(0L,OPS_STATE_RET) & OPS_COMMIT_SWP) {
     printf("auto commit on update #%d\n", counter);
  /* reset OPS_COMMIT_SWP */
  SetOperationState(OPS_COMMIT_SWP,OPS_STATE_OFF);
  }
} while (still not done);
Commit(ctFREE);

The natural use for this mode is with very large transactions, (which consume memory for pre-images), in situations where the client memory must be limited. The system can automatically break large transactions into a series of smaller ones. Of course, this might be a problem since a system crash or an application crash might lead to only a portion of the original large transaction being committed.

The automatic commit will not be attempted if a pending error is outstanding. Such an error can be handled using ctAUTOSAVE, (see above), which causes a high speed, automatic SetSavePoint() after each ISAM update. If an ISAM update incurs an error, use RestoreSavePoint(-1) to go back to the previous savepoint and clear the error.

Return

Begin() returns a transaction number (low word for six-byte transaction numbers) if successful, or zero on error. With six-byte transaction number support, call ctGETHGH() for the high word of the transaction number. It an error occurs Begin() returns 0 and uerr_cod will return the appropriate c-tree error code.

Value

Symbolic Constant

Explanation

70

TEXS_ERR

Transaction already pending - you cannot start one until the prior one is committed or aborted.

99

TTYP_ERR

Transaction type / trnmod conflict.

150

SHUT_ERR

Server is shutting down.

See c-tree Plus Error Codes for a complete listing of valid c-tree Plus error values.

Example

COUNT     savepoint;

void domaster() {
    Begin(ctENABLE|ctTRNLOG);   /* start transaction with locks  */
    while(another()); {     /* get next record to add        */
        savepoint = SetSavePoint(); /* get save point at
                             beginning of each master record */
        if (add_master() < 0)
            Abort();        /* Begin if can't add master rec */
        dodetail();         /* process detail records        */
    }
    if (Commit(ctFREE) != 0)
        printf("\nError %d in transaction",uerr_cod);
    return;
}

void dodetail() {
    while(moredetail()); {   /*get next detail record to add */
        if (add_detail()<0) {    /* add details, if possible */
            RestoreSavePoint(savepoint) /* with error, return
                                                   to savept */
            return;
        }
    }
}

See also

Abort(), AbortXtd(), Commit(), ClearSavePoint(), ctGETHGH(), ctSETHGH(), DeleteRecord(), InitCTreeXtd(), InitISAMXtd(), LockISAM(), RestoreSavePoint(), ReWriteRecord(), SetSavePoint(), SetOperationState(), TRANRDY()