z/OS HCD User's Guide
Previous topic | Next topic | Contents | Index | Contact z/OS | Library | PDF


How to initiate, extend and close a transaction

z/OS HCD User's Guide
SC34-2669-00

How to initiate, extend and close a transaction

To use the transaction facility, you have to:

  • Set up and run the IBM Tivoli Directory Server for z/OS and the HCD LDAP backend as described previously in this information unit.
  • Provide an LDAP V3 client program which uses the appropriate controls of the HCD LDAP backend.

Refer to z/OS IBM Tivoli Directory Server Administration and Use for z/OSz/OS IBM Tivoli Directory Server Administration and Use for z/OS, z/OS IBM Tivoli Directory Server Client Programming for z/OSz/OS IBM Tivoli Directory Server Client Programming for z/OS, and the IBM redbook Understanding LDAP for examples of LDAP client programs.

The following shows some examples of how to use the previously introduced controls on LDAP requests to take the following actions:

  • Initiate a transaction
  • Submit further transaction requests
  • End a transaction

All the following examples written in C, are provided for the LDAP add request (here, we use the LDAP request ldap_add_ext() from the LDAP client API in C).

Please note that you must choose the version of the LDAP client API function which allows you to specify server controls. See the z/OS IBM Tivoli Directory Server Client Programming for z/OSz/OS IBM Tivoli Directory Server Client Programming for z/OS for more information on the functions themselves, as well as on the parameters which have to be passed for particular requests.

Example 1: Initiate a new transaction 

A transaction is initiated using the hcdTransactionControl with NEW as value. This control can be defined the following way:

static LDAPControl hcdTransactionControl_new =
      {
          "1.3.18.0.2.10.3",  /* -- hcdTransactionControl -- */
          { 3, "\x4E\x45\x57\x00" }, /* -- NEW ------------- */
          LDAP_OPT_ON         /* -- critical --------------- */
      } ;
static LDAPControl *hcdTC_new[2] = {  &hcdTransactionControl_new, NULL };

Note, as mentioned before, the value NEW (and also the values COMMIT and ROLLBACK, shown in example 3) have to be specified using UTF-8 encoding.

All controls to be passed to the IBM Tivoli Directory Server for z/OS are stored in an array. In this case, only one control is in the NULL-terminated array.

This array is now be passed to the function which sends the appropriate request to the IBM Tivoli Directory Server for z/OS. For example, ldap_add_ext() is used to request an add operation as follows:

rc = ldap_add_ext( ld, dn, pmods, hcdTC_new, NULL, &msgidp);

Here, the control hcdTC_new is used where the valueNEW was specified in UTF-8.

If this request was successful and if a new transaction was started, the HCD LDAP backend sends back the control hcdTransactionId which contains the transaction ID. Such control may look similar to the following (see also Example 2):

static LDAPControl hcdTransactionId =
       {
          "1.3.18.0.2.10.4",  /* -- hcdTransactionId ------ */
          { 1, "\x31\x00" },  /* -- TXN Id ---------------- */
          LDAP_OPT_ON         /* -- critical -------------- */
       };
static LDAPControl *hcdTC_Id[2] = { &hcdTransactionId, NULL };

In the above example, for the control hcdTransactionId the value indicates a transaction ID of 1.

Note, you should never generate a value for this control on your own. Instead, call the LDAP client API functions ldap_result() and ldap_parse_result() on the response of the first request to obtain the valid transaction ID.

After having issued ldap_add_ext(), calling ldap_parse_result() parses the results which were previously obtained by ldap_result(). Here, among other parameters, the LDAP control containing the transaction ID is provided.

The following code example demonstrates how to use both LDAP requests:

rc = ldap_result(ld, msgidp, 0, NULL, &LDAP_TXN_Msg);
rc = ldap_parse_result(ld, LDAP_TXN_Msg, &errcodep, &matcheddnp,
                      &errmsgp, &referralsp, &servctrlsp, freeit);

The interesting parameter as far as controls are concerned is servctrlsp. This pointer locates an array such as hcdTC_new. The appropriate values of the control have to be copied into the hcdTransactionId control which can be done in the following way (assuming that servctrlsp[0] contains the hcdTransactionId control and the control servctrlsp[0] is not freed):

hcdTransactionId.ldctl_value.bv_val = (servctrlsp[0])->ldctl_value.bv_val;
hcdTransactionId.ldctl_value.bv_len = (servctrlsp[0])->ldctl_value.bv_len;

After these values have been copied, the correct transaction ID can be provided for further LDAP requests which are part of this transaction. This is shown in Example 2 below.

Example 2: Submit further LDAP requests of the transaction. 

After a transaction was successfully initiated, further LDAP requests can be added to the transaction. Here, the user must provide an hcdTransactionId control where value contains the correct transaction ID. As stated before, this control is provided by the HCD LDAP backend and must be used for further requests belonging to this specific transaction.

If we assume that for the transaction we just initiated, the transaction ID number is 1, then, the control which was provided by the HCD LDAP backend would be as follows:

static LDAPControl hcdTransactionId =
       {
          "1.3.18.0.2.10.4", /* -- hcdTransactionId ------ */
          { 1, "\x31\x00" }, /* -- TXN Id ---------------- */
          LDAP_OPT_ON        /* -- critical -------------- */
       };
static LDAPControl *hcdTC_Id[2] = { &hcdTransactionId, NULL };

In general, the values 1 and "\x31\x00" have to be replaced by the correct values of the control that is provided by the call of ldap_parse_result() (see example 1).

After the correct values for this transaction have been copied into the above control, further LDAP requests can be added to the transaction using this control. The call of such an LDAP request is just the same as in example 1 with the only exception that the controls have been exchanged as follows:

rc = ldap_add_ext( ld, dn, pmods, hcdTC_Id, NULL, &msgidp);

As the transaction ID does not change for a specific transaction, all further requests belonging to this transaction must use the same hcdTransactionId control.

Example 3: End a transaction 

Here, two different cases must be considered. As stated before, a transaction can be committed for execution, or it can be aborted by the user using a rollback request.

It is recommended that you explicitly rollback a transaction if a single LDAP request returns a bad return code. The reason for this is that, transactions are intended to represent logical units of requests which belong together. In principal, both the actions - commit and rollback - are the same from an implementation point of view. The only difference is, which control is to be specified for the LDAP request that finishes the transaction. If the user wants to commit a transaction, the following control must be defined:

static LDAPControl hcdTransactionControl_commit =
       {
          "1.3.18.0.2.10.3",    /* -- hcdTransactionControl -- */
          { 6, "\x43\x4F\x4D\x4D\x49\x54\x00" },/* - COMMIT -- */
          LDAP_OPT_ON           /* -- critical --------------- */
       };
static LDAPControl *hcdTC_commit[3] = { &hcdTransactionControl_commit,
                                        &hcdTransactionId, NULL };

If the user want to rollback a transaction, the following control must be defined:

static LDAPControl hcdTransaction_rollback =
       {
          "1.3.18.0.2.10.3",    /* -- hcdTransactionControl -- */
          { 8, "\x52\x4F\x4C\x4C\x42\x41\x43\x4B\x00" }, /*ROLLBACK*/
          LDAP_OPT_ON           /* -- critical --------------- */
       };
static LDAPControl *hcdTC_rollback[3] = { &hcdTransactionControl_rollback,
                                          &hcdTransactionId, NULL };

Using these controls, the final request will, in the case of commit, now be:

rc = ldap_add_ext(ld, dn, pmods, hcdTC_commit, NULL, &msgidp);

and in the case of a rollback:

rc=ldap_add_ext(ld, dn, pmods, hcdTC_rollback, NULL, &msgidp);

If you look at the previous definition of hcdTC_commit and hcdTC_rollback, both parameters are control arrays that contain the commit or rollback control itself, and in addition, also contain the control hcdTC_Id for submitting the next request. Hence, one control indicates the end of the transaction, and the other control identifies the transaction on the basis of its ID. Once a transaction is closed, no further requests can be added to this control.

Go to the previous page Go to the next page




Copyright IBM Corporation 1990, 2014