简体   繁体   中英

Use of SQLAllocHandle(SQL_HANDLE_ENV, …) in a multi-process system

I want to make sure I am implementing connections properly in a multi-process system. Specifically, the environment handle.

SQLAllocHandle seems to be used by several database vendors. My immediate interest is in DB2, but I would also like to know about how this is handled by other vendors.

The examples I find on the web allocate the environment handle, then immediately allocate the database handle. I presume the examples are for single process systems so in that context they make sense. Something like this pseudo code:

SQLHANDLE connenv = NULL;
SQLHANDLE conn = NULL;

int connectEnv(void)
{
   connenv = NULL;
   if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &connenv))
   {
      printf("Fail to allocate memory for connenv");
      return 0;
   }

   return 1;
}

int connectDbc(void)
{
   conn = NULL;

   if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_DBC, connenv, &conn))
   {
      SQLFreeHandle(SQL_HANDLE_ENV, connenv);
      printf("Fail to connect to database");
      return 0;
   }

   if (SQL_SUCCESS != SQLConnect(conn, conninfo, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS))
   {
      printf("unable to allocate connection %s", conninfo);
      return 0;
   }
   return 1;
}

int main(int argc, char *argv[]) {
   while (1) {
       waitForReasonToStartChild()
       if (fork()) {
          // parent process

       } else {
          // child process
          connectEnv();
          connectDbc();
       }
   }
}

To save time, I would like to move the allocation of the environment handle to the parent process and leave the database connection in the child process.

int main(int argc, char *argv[]) {
   connectEnv();
   while (1) {
       waitForReasonToStartChild()
       if (fork()) {
          // parent process

       } else {
          // child process
          connectDbc();
       }
   }
}

This just seems to make more sense to me (even if it was not faster), but I have not found examples on the web.

Is that the proper way to do it? Are there other techniques that are better?

The first link I found for multi-threading for DB2 ODBC has an example like your preferred approach.

The link is http://www-01.ibm.com/support/knowledgecenter/api/content/SSEPEK_11.0.0/com.ibm.db2z11.doc.odbc/src/tpc/db2z_lethrd.html

To summarise, the parent thread allocates the environment, then each child thread (two in the example shown) allocates its own connection handle and uses it:

  1. Creates two child Language Environment threads from an initial parent thread. The parent thread remains active for the duration of the child threads. DB2 ODBC requires that the thread that establishes the environment handle must persist for the duration of the application. The persistence of this thread keeps DB2 language interface routines resident in the Language Environment enclave.
  2. Connects to database A with child Language Environment thread 1 and uses SQLFetch() to read data from this connection into a shared application buffer.
  3. Connects to database B with child Language Environment thread 2. Child Language Environment thread 2 concurrently reads data from the shared application buffer and inserts this data into database B.
  4. Calls Pthread functions to synchronize the use of the shared application buffer within each of the child threads.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM