Method and apparatus for transaction processing in a distributed database system5978577Abstract A subscriber management system includes at least one Data Directory Server (DDS) located between one or more transaction generators and one or more data servers. The DDS efficiently routes transactions and provides data location functions. The DDS provides high data availability, high on-line transaction rates, batch capabilities, scalability and maintainability. In particular, based upon internal rules within the DDS and the particular transaction type, the DDS routes transactions to the appropriate server(s). Transactions are classified according to where they may be executed. Specifically, transactions may be classified as SPECIFIC, ANY or ALL. A SPECIFIC transaction must be processed at one or more specific servers irrespective of the accompanying arguments. An ANY transaction may be processed at any of the enterprise servers and selection is made randomly. Finally, an ALL transaction requires sequencing through each of the data servers within the enterprise and repetitively performing the transaction. Claims We claim: Description BACKGROUND OF THE INVENTION
______________________________________
class ServerTbl
private:
SrvInfo *.sub.-- server;
//server information
structure
CS.sub.-- INT
.sub.-- next; //next server name
CS.sub.-- INT
.sub.-- serverCnt;
//server count
protected:
ServerTbl();
public:
ServerTbl(CS.sub.-- CHAR*,
constCS.sub.-- CHAR*);
.about.ServerTbl();
CS.sub.-- CHAR
*GetNext();
CS.sub.-- CHAR
*GetUID(); //inline
CS.sub.-- CHAR
*GetPswd(); //inline
CS.sub.-- INT
GetCnt(); //inline
CS.sub.-- CHAR
*GetSpecific(CS.sub.-- INT i);
//inline
CS.sub.-- VOID
UpdateTbl(CS.sub.-- CHAR*,
const CS.sub.-- CHAR*);
}
______________________________________
As can be seen, this definition identifies the server information structure, the next available server and the number of servers of a specified type. It is to be understood that the class definition illustrated above is given by way of example only and is by no means the only possible class definition which may be employed in the present invention. The ServerTbl class definition includes the .sub.-- server information structure pointer which supports a list of available servers specified by the class instantiation and contains the server name, a user ID and a password. The user ID and password are available for use with any system administration functionality that supports the DDS server. The .sub.-- next data member is an integer value that contains the next element of the .sub.-- server list (the next available server). It is possible to access this information through a calling routine discussed below. Finally, the .sub.-- serverCnt element is included. This member is an integer value containing the number of servers available to the calling routine. The Server Table class definition of the preferred embodiment also contains various member functions. The class constructor ServerTbl (CS.sub.-- CHAR *, const CS.sub.-- CHAR *) takes as arguments the type of server (XRef or DDS) and the server data table name. When called, this constructor initializes the member data and calls the UpdateTbl function with the same arguments. As a result, the server table can be initialized and built. The UpdateTbl function performs all of the DDS data file management to obtain the required information concerning a specified server. In addition, this function serves to build the Server Table. The GetNext function returns the next available server in the instantiated table. This function provides a level of randomization to evenly distribute server request loads. The GetUID function returns the current user ID for the specified server. The GetPswd function returns the current user password for the specified server. The GetCnt function returns the current number of servers of the instantiated type. Finally, the GetSpecific function returns a specifically requested server table entry. The next class to be discussed is the Server Name class. Again, various functions are associated with this class, in this case to allow the DDS to select a stored procedure. The server name is represented by this class definition which identifies the current server table element and the procedure element requesting the server name. The Server Name class definition of the preferred embodiment is provided below:
______________________________________
class SrvName
private:
ProcElem *.sub.-- p;
CS.sub.-- INT
.sub.-- arg Val;
CS.sub.-- INT
.sub.-- curElem;
public:
SrvName(ProcElem*,CS.sub.-- VOID**);
.about.SrvName();
SrvElem *GetNext(SrvElem*&);
SrvName& operator=(const SrvName&);
CS.sub.-- INT
GetSrvCnt();
CS.sub.-- INT
GetSrvTyp();
};
______________________________________
The Server Name class identifies the current server table element that supports the current stored procedure in the procedure list. In addition, this class provides data elements that point to the current stored procedure in the procedure list table. Finally, the class stores parameters associated with the current stored procedure and a current element flag. The .sub.-- p data member is a pointer to the procedure list table stored in the DDS. The .sub.-- argVal data member contains an integer value that identifies the argument position for any rule based stored procedure. The .sub.-- curElem member is an integer which represents the currently selected procedure from the procedure list. The GetNext() member function applies the rules for retrieving the appropriate server name. As will be discussed below, this is necessary when the DDS must process an "ALL" or an "ANY" request. The GetSrvCnt() simple returns the number of servers associated with the current stored procedure. The GetSrvTyp() returns the distributed transaction processing (DTP) code back to the requester. As will be discussed below, the DTP code refers to a particular processing paradigms including ANY, ALL and SPECIFIC. The class constructor and destructor functions allocate memory and construct the server table and deallocate and release the table respectively. An additional function provides a mechanism to return the name of the next server in the list. The member functions for the Server Name class are illustrated in Table 1.
TABLE 1
______________________________________
SERVER NAME CLASS FUNCTIONS
* SrvName :: SrvName(ProcElem *.sub.-- p, void **argList)
Assign procedure element .sub.-- p to SrvName class variable.
If the argList a is not NULL
Assign the argument position value to the class variable
initialize the current element class variable to 1
* SrvName :: GetNext( )
if (-P-> firstSrv) // GROUP
if((.sub.-- p->dtpCode ==ALL)&&
(.sub.-- curElem<=.sub.-- p>elemCnt))
curSrv = .sub.-- p->firstSrv[.sub.-- curElem - 1]
++.sub.-- curElem
else if ((.sub.-- p ->dtpCode == ANY) && (.sub.-- curElem == 1))
rNum = .sub.-- p->firstSrv[GetRandom( )]
++.sub.-- curElem
else if ((.sub.-- p ->dtpCode == SPECIFIC) &&
(.sub.-- curElem == 1))
curSrv = .sub.-- p->firstSrv[.sub.-- curElem - 1]
++.sub.-- curElem
else
retrieval is complet, return a NULL pointer value
reset .sub.-- curElem to 1
else if(.sub.-- p -> firstRule)
for i = 0; i < .sub.-- p->firstCnt; i++
if .sub.-- argVal == NULL
set curSrv to NULL
the parameter for this stored procedure
is missing
if .sub.-- argVal <= .sub.-- p -> firstRule[i] -> high.sub.-- val
&&
.sub.-- argVal >= .sub.-- p -> firstRule[i] -> lowVal &&
.sub.-- curElem == 1
curSrv = .sub.-- p->firstSrv[i].servers
curSrv -> dbName = .sub.-- p->dbName
increment .sub.-- curElem
break out of for loop
else if .sub.-- curElem > 1
set curSrv to NULL
reset .sub.-- curElem to 1
break out of for loop
else
continue
end for loop
else
set curSrv to NULL
there is a problem with the XRef Data Tables
return curSrv;
* SrvName :: GetSrvCnt( )
return .sub.-- p->firstCnt
*SrvName :: GetSrvTyp( )
return .sub.-- p->dtp.sub.-- code
______________________________________
The next group of classes to be discussed relate to the XRef Data tables. The XRef Data tables consist of database information that supports the decision making requirements to access the various data servers supporting the SMS application. Four tables located within the XRef Server contain information related to: o all of the stored procedures available for a client to submit to the DDS; o all of the data servers accessible by the DDS; o the various server groups that the data servers fall into; and o the rule boundary information that binds the rule based stored procedures to the data server(s) that can support the client request. This information is retrieved from the XRef Server by the DDS application at startup. The data is stored in three tables internally within the DDS. The three internal tables are: 1) Procedure table--which consists of all stored procedures; 2) Server table--which consists of all data server data; and 3) Rule table--which consists of all decision rule data The data structures for these tables are constructed by stored procedures that return results in a format consistent with DDS internal storage format. Each of these tables is supported through the XRef class definition and is given below:
______________________________________
struct SrvElem
char SrvName[MAXNAME];
char warmSrv[MAXNAME];
char grpName[MAXNAME];
int srvConn;
int warmConn;
};
struct RuleElem
{
char ruleName[MAXNAME];
int lowVal;
int highVal;
char srvName[MAXNAME];
SrvElem *servers
};
struct ProcElem
{
char procName[MAXNAME];
char grpName[MAXNAME];
char ruleName[MAXNAME];
char srvName[MAXNAME];
char dbName[MAXNAME];
PROC.sub.-- TYPE
pType;
DTP.sub.-- CODE
dtp;
int argPos;
int firstCnt;
SrvElem *firstSrv;
RuleElem *firstRule;
};
______________________________________
The XRef Data tables are represented by a class that defines data structures for the stored procedure list, the server list and the rules list. A count is also maintained for each of the lists. The XRef Data table class of the preferred embodiment is given next:
______________________________________
class XRefDataTbl
private:
ProcElem *.sub.-- procList;
SrvElem *.sub.-- srvList;
RuleElem *.sub.-- ruleList;
CS.sub.-- INT
.sub.-- procCnt;
CS.sub.-- INT
.sub.-- srvCnt;
CS.sub.-- INT
.sub.-- ruleCnt;
protected:
XRefDataTbl();
public:
XRefDataTbl();
.about.XRefDataTbl();
CS.sub.-- INT
GetProcCnt();
//inline
CS.sub.-- INT
GetSrvCnt();
//inline
ProcElement *GetProcList();
//inline
CS.sub.-- RETCODE
GetServer(CS.sub.-- CHAR*,CS.sub.-- VOID**,
SrvName*);
CS.sub.-- RETCODE
UpdateTbl(CS.sub.-- CHAR*,CS.sub.-- CHAR*,
CS.sub.-- CHAR*);
CS.sub.-- RETCODE
RunRpc(CS.sub.-- CONNECTION*,CS.sub.-- CHAR*,
CS.sub.-- INT);
CS.sub.-- RETCODE
BldList();
};
______________________________________
The .sub.-- procList member data is a pointer to the list of stored procedures stored in the XRef data tables within the DDS. The .sub.-- srvList member data is a pointer to the list of data servers stored in the XRef data tables within the DDS. The .sub.-- ruleList member data is a pointer to the list of rules stored in the XRef data tables The .sub.-- procCnt member data is an integer value containing the number of stored procedures stored in the .sub.-- procList. The .sub.-- SrvCnt member data is an integer value containing the number of data servers stored in the .sub.-- srvList. Finally, the .sub.-- rulecnt member is an integer value containing the number of rules stored in the .sub.-- ruleList. The member functions include a class constructor and destructor for creating and releasing the lists. Further the GetServer() member function retrieves a server name based on the procedure name and its arguments. As mentioned above, the XRef data tables are constructed through the class instantiation and are linked together based on the procedure names and its type. The XRef Data Table constructor function calls the table update member function that initialized the table element counts. It also calls the update function to build the tables. The GetrocCnt(), GetSrvCnt() and GetProcList() member functions are inline functions that return the number of stored procedures in the procedure list, the number of servers in the server list, and a pointer to the procedure list respectively. Table 2 illustrates the member functions associated with the XRef Data Table class in the preferred embodiment.
TABLE 2
______________________________________
XREF DATA TABLE CLASS FUNCTIONS
The object constructor is as follows:
XRefDataTbl::XRefDatatbl( )
initialize the procedure, server, and rule counts to zero
if(UpdateTbl(CS.sub.-- CHAR *server, CS-CHAR *uid,
CS.sub.-- CHAR *pswd)!= CS .sub.-- SUCCEED)
exit out of the function
The UpdateTbl function represents the XRef data table update
function that builds the XRef data tables from the XRef Server.
XRefDataTbl::UpdateTbl(CS-CHAR *server, CS..sub.-- CHAR *uid,
CS-CHAR *pswd);
Set up the client interface to the XRef Server
This is a standard client library interface set up
Run the stored procedure "lp.sub.-- get.sub.-- srv-cnt" to retrieve the
number of servers stored in the database.
if it fails, there is a problem with the XRef Table Data
Run the stored procedure "lp.sub.-- get.sub.-- rule.sub.-- cnt" to
retrieve the
number of rules stored in the database.
if it fails, there is a problem with the XRef Table Data
Run the stored procedure "lp.sub.-- get.sub.-- proc.sub.-- cnt" to
retrieve the
number of procedures stored in the database.
if it fails, there is a problem with the XRef Table Data
Allocate sufficient memory to store the number of rows for
the server list.
Run the stored procedure "lp.sub.-- get.sub.-- srv.sub.-- list"
to retrieve the data from
the SERVER.sub.-- GROUP and SERVER tables.
Allocate sufficient memory to store the number of rows for
the rule list.
Run the stored procedure "lp.sub.-- get.sub.-- rule.sub.-- list"
to retrieve the data from the
RULE-BOUNDARY and SERVER tables.
Allocate sufficient memory to store the number of rows for
the procedure list.
Run the stored procedure "lp.sub.-- get.sub.-- proc.sub.-- list"
to retrieve the data from
the PROCEDURE table.
Integrate the lists by calling the BldList( ) function
Exit and clean up the client application
};
The Build List function builds the lists such that the three XRef data
tables are interlinked to provide a quick access to the desired server
name based on the stored procedure issued by the user.
XRefDataTbl::BldList( )
For every row returned from "lp-get.sub.-- proc.sub.-- cnt`
link the structure
if procList->pType == GROUP
sequentially search srvList for srvList->
grpName == procList->grpName
store first srvList element in procList->firstSrv
assign procList->firstRule = NULL
initialize first count to zero
sequentially search srvList and count the number of
servers supporting the server group
store the count of the number of server in
procList->firstCnt
else if procList->pType == RULE
sequentially search ruleList for
srvList->ruleName==procList->ruleName
store first ruleList element in procList->firstRule
assign procList->firstSrv = NULL
sequentially search ruleList and count the number of
rules supporting the server group
store the count of the number of rules in
procList->firstCnt
sequentially search server List for server name
assign server pointer to server list element
else // procList->pType == SPECIFIC
sequentially search server list for server name
assign firstSrv to the server list element
assign NULL to firstRule
assign 1 to firstCnt
break out of for loop
};
The Run RPC function issues the command to the remote data
server and processes the results.
XRefDataTbl::RunRpc(CS-CONNECTION *conptr,
CS.sub.-- CHAR *cmd, CS.sub.-- INT cmdType)
{
Allocate the command structure
Initiate the command
Send the command
Process the results based on the command type
This functionality is specific to the type of command issued
Drop the command structure
}
The get server function searches the stored procedure list for a
particular stored procedure and creates a server name class object
to point to the first server supporting that stored procedure.
CS.sub.-- RETCODE
XRefDataTbl::GetServer(char *procname, void **argList,
SrvName *server)
{
Perform a binary search of the procedure list for the
current stored procedure if it fails to get an entry,
return CS - FAIL;
Create server name object server for the procName and argList
Assign server name to return parameter
Return CS.sub.-- SUCCEED;
}
______________________________________
The DDS requires the Xref Data Table and Server Table information to operate in the SMS environment. The tables are used to locate the appropriate data server(s) to satisfy a client's stored procedure request. Additional stored procedures will continuously be added to the client's application to facilitate new and enhanced features in the SMS environment. These new stored procedures must be included in the Xref server data table to complete the implementation of the features which, in turn, requires a reload for the DDS internal tables. Also, additional data servers and DDS's may be added to the SMS. New servers must be added to the DDS data table as well as to the Xref server data table so as to include these servers in the DDS internal tables. The next class to be discussed is the ClntUsrData class. The ClntUsrData class is used as a means of encapsulating information needed by a client service thread in the DDS open server application. This class is constructed in the connection handler and is pointed to by the user data for the client's internal client thread control structure. The data is encapsulated within self-describing data objects including both the data itself and the type or format of the representation of the information. In this way it is unnecessary to access the related class descriptors or class definitions to retrieve the required semantic information. Through encapsulation, the data can be retrieved easily within any of the handlers that a client thread may enter. The ClntUsrData class of the preferred embodiment is:
______________________________________
class ClntUserData
private:
FMT.sub.-- CTL* .sub.-- fmtCTL;
Ucon* .sub.-- ucon;
public:
ClntUsrData(int numSrvs,
LoginData & loginData,
CmdConPool*cmdConPoolPtr);
.about.ClntUsrData();
virtual Ucon* GetUcon(); //inline
virtual FMT.sub.-- CTL
*GetFmtCtl();
//inline
}
______________________________________
The ClntUsrData class provides a repository for information related to a client's user data which is stored and reused with the client's thread properties. This class encapsulates format control information needed to process result sets in the "ALL" scenario (discussed below) and user connection objects that allow a client to re-use remote server connections. There exists one ClntUsr Data class allocation for each client accessing the DDS. The .sub.-- fmtCt1 member data variable contains encapsulated information needed by several functions when processing results for an "ALL" scenario in the DDS application. The .sub.-- ucon member data variable is a user connection object that allows a DDS client to re-use its remote server connections, saving the overhead of continually re-opening connections. It is an object that abstracts and organizes client connections. The ClntUsrData() only constructor uses its arguments to allocate the .sub.-- ucon object. It also allocates and initializes a FMT.sub.-- CTL structure. The .about.ClntUsrData() destructor de-allocates .sub.-- ucon and .sub.-- fmtCtl which were allocated by the constructor. The GetFmtCtl() inline member function returns the private .sub.-- fmtCtl data member and the GetUcon() inline member returns the private .sub.-- ucon data member. The TopRPCList class ranks the most used RPC's, calculating each RPC's average execution time and returning the name, number of executions, and the average execution time to the requesting client. This class is called from the rp.sub.-- mon.sub.-- rpc registered procedure and is invoked when the DDS Control Application submits a monitoring request. All of the processing for this class is invoked from the constructor; no other member functions need be called by the user. The inherited TopList member functions do most of the underlying ordering work. The TopRPCList class of the preferred embodiment is:
______________________________________
class TopRPCList: public TopList
protected:
virtual COMPARE.sub.-- CD CompareFunc(void *)
public:
TopRPCList(SRV.sub.-- PROC*srvProcPtr,
ProcElement* rpcListPtr,
CS.sub.-- INT rpcListSize,
CS.sub.-- INT topListSize);
.about.TopRPCList() {}
};
______________________________________
The protected virtual function CompareFunc(void * item) provides a complete definition for the pure virtual function declared by TopList. This function compares the item >cumNumRuns against the .sub.-- current->cumNumRuns and returns a COMPARE.sub.-- CD. The TopRPCList (SRV.sub.-- PROC * srvProcPtr, ProcElement * rpcListPtr, CS.sub.-- INT rpcListSize, CS.sub.-- INT topListSize) constructor builds a list of topListSize ranked by the frequency of executions of RPC's in the array pointed to by rpcListPtr. The RPC list is of size rpcListSize. The RPC list and its size are defined in the XrefDataTbl class for the DDS. Once the list is loaded, this member function walks through the list, returning results to the requesting client. Each row contains the rpc.sub.-- name, the number of executions, and the average execution time for the RPC. The average execution time is calculated by dividing the cumSeconds by the cumNumRuns as stored in the ProcElement in the XRefDataTbl. RPC Handler The DDS of the present invention processes a great majority of client requests through the RPC Handler which is now discussed. The DDS accepts client stored procedure requests and first investigates the resident registered procedure list table to locate the RPC in question. If the RPC is found in the table, the procedure is executed locally. If the RPC is not found in the table, the DDS raises a RPC Handler event and relinquishes control to the handler routine. The RPC Handler processes all client stored procedure requests to determine which of the data servers should service the request. The RPC Handler provides a semi-passthru capability for client requests that require selection of specific data servers that can support the client's request. This results in a single result set from the specified data server. The RPC Handler also supports stored procedure requests from client applications that access several data servers at a time in the same group. This allows for multiple result sets being passed back to the requesting client. In semi-passthru mode, the system parses the incoming client RPC command request and the RPC command result set is passed thru the intermediate DDS directly to the client. The incoming client command requests are parsed to identify the request and any parameters associated with the command. The command request and its parameters are used to identify the appropriate data server to best service the request. The process flow for the RPC Handler process is illustrated in FIG. 3 and is now discussed. Initially and upon a request for service from a client, the user data (including username, password, etc.) regarding such client is obtained. The DDS can use this information to set up a User Connection Object. The RPC command name is then retrieved from the data stream as are the number of RPC parameters associated with the RPC command, and the RPC parameters if they exist. The RPC Handler then causes the appropriate Server name(s) for the remote procedure call to be determined. This is generally accomplished by getting the next server element. At this point, in a preferred embodiment of the instant invention, the RPC Monitoring functionality is instantiated so that the control with respect to request servicing may be optimized. The DDS then determines if a connection to the selected server(s) exists. If so, then the request is submitted to that server. If no connection exists, then one is set up. If the request was an "ALL" request (i.e. a read from or write to all data servers in the SMS system) then the result sets from all data servers are received by the DDS as part of the RPC Handler process flow. Otherwise, for requests directed to single or a group of data servers, the result sets are returned to the requesting client in passthru mode through the DDS. ALL, ANY, SPECIFIC The present invention acts on various scenarios for efficiently allocating requests to data servers based upon the type of transaction involved. This aspect of the invention will now be discussed in detail with reference to FIGS. 4(a) and 4(b). FIG. 4(a) is a data flow diagram illustrating the data and decision making process in selecting a server based upon an "ALL", "ANY" or "SPECIFIC" data request. As will be discussed in further detail below, a "SPECIFIC" request corresponds to a Procedure Type=Server and an "ANY" or "ALL" request corresponds to a Procedure Type=Group. The "ANY" scenario will be discussed in detail now. It is to be understood that some or all of the steps next discussed may be omitted and additional steps may be added while still remaining within the spirit of the invention. FIG. 4(b) illustrates the important steps in the process while the ensuing discussion elaborates on the steps and adds additional, optional steps. Initially the client will issue an RPC request to the DDS. At this point the DDS will raise an RPC event which is handled by the RPC Handler functionality of the DDS. Next, the RPC counter is incremented to indicate that an active RPC is present in the DDS. At this point the user data corresponding to the client thread properties is obtained and the user connection information is set up. Once the preliminary setup is accomplished, the RPC command and its arguments are retrieved from the client request data stream. The DDS then obtains the appropriate data server information based upon the RPC command issued by the client. If desired, the procedure list information is obtained from the data server information and is used to instantiate the RPC Monitor object to start the timing of the current RPC. The GetNext function then gets the next data server in the available server list based on the procedure type and, if applicable, its argument list. In the "ANY" scenario, the DTP code would indicate that the client's stored procedure could be sent to ANY data server in the server list supporting the server group. The DDS randomly selects a data server name from the server list. Additionally, an automatic retry mechanism may be included so that the DDS selects another server from the list of available servers in the event the DDS is unable to connect to the first server selection. Next, the GetCmdCon function is called to get or make a connection to the selected data server. The SendRpcCmd function then sends the RPC command and its argument set, if any, to the data server. After processing by the selected data server(s), a result set is returned to the DDS. The GetSrvTyp function is then invoked and returns the DTP code back to the RPC Handler. The "ANY" scenario utilizes the pass through capabilities of the DDS Open Server to process the result set. Thus the data stream returned from the data server can be sent back to the requesting client without disturbance. This is accomplished once the active command/connection object is obtained. Once the result set is returned to the client, the DDS issues a send done final to the client indicating that the data transfer is complete. The EndRPC function is then invoked to stop the timing of the current RPC. Next the data server object is released and the active RPC count is decremented. The "SPECIFIC" scenario, which is used to select a single, individual server follows the same process as described above with respect to the "ANY" scenario except that the "SPECIFIC" scenario specifies rule based procedures or specific server procedures. The rule based procedure scenario selects the appropriate data server based on the data distribution rules and boundaries while the specific server procedure scenario uses the server name associated with the stored procedure. The "ALL" scenario, which calls for a query or update to all data servers supporting the group, is processed as follows. Again it should be understood that some or all of the steps next discussed may be omitted and additional steps may be added while still remaining within the spirit of the invention. FIG. 4(b) illustrates the important steps in the "ALL" scenario processing while the ensuing discussion elaborates on the steps and adds additional, optional steps. Initially the client will issue an RPC request to the DDS. At this point the DDS will raise an RPC event which is handled by the RPC Handler functionality of the DDS. Next, the RPC counter is incremented to indicate that an active RPC is present in the DDS. At this point the user data corresponding to the client thread properties is obtained and the user connection information is set up. Once the preliminary setup is accomplished, the RPC command and its arguments are retrieved from the client request data stream. The DDS then obtains the appropriate data server information based upon the RPC command issued by the client. If desired, the procedure list information is obtained from the data server information and is used to instantiate the RPC Monitor object to start the timing of the current RPC. The GetNext function then gets the next data server in the available server list based on the procedure type and, if applicable, its argument list. In the "ALL" scenario, the DTP code would indicate that the client's stored procedure must be sent to ALL data servers in the server list supporting the server group. The GetNext, GetCmdCon and SendRpcCmd functions are iteratively called until the server list has been completely traversed. The GetCmdCon function is called to get or make a connection to the selected data server. The SendRpcCmd function then sends the RPC command and its argument set, if any, to the data server. For every RPC command sent to the data servers, the SendRpcCmd function establishes an Open Client environment that sends the RPC message to the SQL servers. Result sets are returned from the data servers in a random order back to the Open Client environment in the RPC Handler. The RPC Open Client sends the result sets back to the DDS. The GetSrvTyp function is then invoked and returns the DTP code back to the RPC Handler and processes multiple result sets in this scenario. The active command/connection object is obtained and while there are active commands outstanding, the result sets are retrieved and sent to the client. The RPC Handler then sends a send done MORE indication to the DDS, sets the command/connection to inactive and sends the MORE indication to the client. The MORE indicator informs the client to wait for additional result sets. As result sets are sent to the client the connections are marked inactive to indicate that the result set was retrieved from the data server. Once all of the result sets are returned to the DDS, the DDS issues a send done final to the data server and ultimately to the client indicating that the data transfer is complete. The EndRPC function is then invoked to stop the timing of the current RPC. Next the data server object is released and the active RPC count is decremented. Utility Functions A set of utility functions have been developed to support the operations of the DDS. These functions are now described. Command Connection Pool Service The CmdConPoolSrvc object provides a mechanism to close all connections that have met or exceeded a time out limit. The time out limit is the period of time this process sleeps which is a DDS Open Server configurable time threshold. The CmdConPoolSrvc object does not have any input parameters. The CmdConPoolSrvc object provides output information to the DDS Error Handler which is directed to standard error and/or the DDS log file. The CmdConPoolSrvc object returns CS.sub.-- SUCCEED or CS.sub.-- FAIL. Free Parameter Memory The FreeParamMem object frees any allocated memory associated with the Remote Procedure Call parameters passed by the client application. This object first cheeks if any parameters exist and frees all the allocated memory. The FreeParamMem object accepts the following input parameters: paramCnt--An integer count of the number of parameters associated with the RPC Name. fmtptr--A pointer to a data format structure that will contain the format of the data received from the client in the RPC Handler. paramDataPtr--A pointer to an array of pointers that will contain the actual RPC command parameter values. paramLenPtr--An integer pointer that contains the length of each of the parameter values. indPtr--A small integer pointer that is require to hold the null indicator for each parameter supplied by the client process and is required to bind the local variables. The FreeParamMem object does not output any information to standard output. The FreeParamMem object does not return any values to the calling object. Get RPC Command The Get RPC command object is used in the RPC Handler and obtains the name of the client supplied Remote Procedure Call and the associated parameters, if any. If parameters exist, this object allocates memory for the local variables, binds the parameter to the local variables, and transfers the data from the TDS to the local variables. The GetRpcCmd object accepts the following parameters: srvProcPtr--Service thread pointer for the current client thread. rpcNamePtr--A character string that points to the client supplied stored procedure name. paramCnt--An integer count of the number of parameters associated with the RPC Name. frntptr--A pointer to a data format structure that will contain the format of the data received from the client in the RPC Handler. paramDataPtr--A pointer to an array of pointers that will contain the actual RPC command parameter values. paramiLenPtr--An integer pointer that contains the length of each of the parameter values. indPtr--A small integer pointer that is require to hold the null indicator for each parameter supplied by the client process and is required to bind the local variables. All the input parameters, except for the service thread pointer, are passed to the GetRpcCmd by reference. The GetkpcCmd object does not provide any output to the standard output. All data is returned to the calling object through the input parameters which are passed by reference. The GetRpcCmd object returns CS.sub.-- SUCCEED or CS.sub.-- FAIL to the calling object. Install Registered Procedures The InstallRegProcs object is the single point of installation of all the registered procedures stored in the DDS Open Server application. The InstallRegProcs object defines and creates all the registered procedures and any associated parameters in the Open Server registered procedure list table. In a preferred embodiment, this object installs the following registered procedures, which are presented in connection with the discussion on registered procedures. OsShutdown SetFilter SetLogFIag MonLog MonRpc The InstallRegProcs object does not accept any input parameters. The InstallRegProcs object does not provide any output to standard output. The InstallRegProcs object returns CS.sub.-- SUCCESS or CS.sub.-- FAIL to the calling object. Process Command Line Arguments The ProcArgs object processes the DDS command line arguments whenever the DDS is started. The command line arguments are extensive, but they allow the user to dynamically control how the DDS is configured on startup. The DDS argument list provides the ability to control at least the following parameters: NETBUFSIZE is used to set the maximum size of the network I/O buffer to be used by the client connections. NUMREMBUF controls the window size used on server-to-server connections. It indicates the maximum number of packets that can be outstanding on a logical sub channel before an acknowledgment is required. NUMCONNECTIONS indicates the maximum number of physical network connections the Open Server application will accept. NUMTHREADS specifies the maximum number of treads available to the DDS application. LOGFLAG is a flag that directs the error message to either standard error, the log file or both. NUMREMSITES indicates the maximum number of remote server site handlers that can be active at a given time.STACKSIZE defines the size of the stack allocated for each thread.SERVERNAME specifies the name of the DDS application. The ProcArgs object accepts the following input parameters: argc--An integer count of the number of arguments presented on the command line argv--An array of character string pointers that contain the actual input parameter values. nonSybProps--An class object that is passed by reference to hold all the non Sybase Open Server properties. The ProcArgs object provides a usage statement to standard error if an invalid argument is detected on the command line. The ProcArgs object returns CS.sub.-- SUCCEED or CS.sub.-- FAIL. Process Configuration The ProcConfig object opens the dds.sub.-- config.dat file and configures the DDS application with any of the specified properties and flags. The properties and flags are the same as the command line settable properties and flags. Also, if any command line properties and flags are specified when the DDS is started, the command line options will override any configuration file properties or flag settings. The ProcConfig object ignores any property or flag that are misspelled or missing any required argument. The ProcConfig object accepts the following input parameters: ctxptr--A pointer to the context structure for the DDS Open Server application. nonSybProps--A class object passed by reference to record any non Sybase Open Server properties that need to be set in the DDS Open Server application. This object outputs error information through the DDS Error Handler functionality to standard error and/or the Open Server log file. The ProcConfig object returns CS.sub.-- SUCCEED or CS.sub.-- FAIL. Send RPC Command The Send RPC command object sends the RPC command and its parameters to the remote data server. This object constructs a character string that contains the database name and the RPC name and issues a client command to the destination data server along with any associated RPC parameters. The SendRpcCmd object accepts the following parameters: cmdptr--A pointer to the command structure, that is used to send commands to a server. rpcNamePtr--A character string that contains the client supplied RPC command name. dbname--A character string that contains the name of the database that contains the RPC command. paramDataPtr--A pointer to an array of pointers that will contain the actual RPC command parameter values. fmtptr--A pointer to a data format structure that will contain the format of the data received from the client in the RPC Handler. paramCnt--An integer count of the number of parameters associated with the RPC Name. paramLenPtr--An integer pointer that contains the length of each of the parameter values. indPtr--A small integer pointer that is require to hold the null indicator for each parameter supplied by the client process and is required to bind the local variables. The SendRpcCmd object does not provide any output to the standard output. The SendRpcCmd object returns CS.sub.-- SUCCEED or CS.sub.-- FAIL to the calling object. The SendRpcCmd object constructs an error message and sends the message to the DDS Error Handler. Server Message Callback The ServerMsgCB object accepts the following input parameters: ctxPtr--A pointer to the context structure for which the message occurred. conPtr--A pointer to the connection structure for which the message occurred. srvMsg--A pointer to the CS.sub.-- SERVERMSG structure containing server message information. The ServerMsgCB object provides an output message that is logged with the DDS Error Handler object that outputs the message to standard error and/or the Open Server log file. The ServerMsgCH object only returns CS.sub.-- SUCCEED. In addition to the above DDS utility functions, a set of general utility functions have been developed to support the general operations of the DDS application. These functions are now discussed. CONNECT SERVER The connect server object establishes a connection to the specified data server using the login user id and password parameters. This object allocates a connection pointer structure for the specified context of the DDS, sets the connection properties for user name and password, and establishes the connection to the data server. The ConnectServer object accepts the following input parameters: ctxPtr--A pointer to the context structure. conPtr--The address of a pointer of a newly allocated connection structure. sqlsrv--A character string that contains the name of the data server to be connected to. usrId--A character string that contains the client users identification used to connect to the data server. pswd--A character string that contains the client password used to connect to the data server. The ConnectServer object provides no information to standard output. The ConnectServer object returns CS.sub.-- SUCCEED or CS.sub.-- FAIL. Get User Information The GetUserInfo object accesses the thread properties and extracts the user id and password associated with the internal thread control structure. The GetUserlnfo object accepts the following input parameters: srvProcPtr--A pointer to an internal thread control structure usrld--A character string pointer that will contain the user identification from the thread properties. pswd--A character string pointer that will contain the user's password from the thread properties. The GetUserlnfo object provides no information to standard output or the DDS Error Handler. The GetUserlnfo object returns CS.sub.-- SUCCEED or CS.sub.-- FAIL. Manage Format Pointer The ManageFmtPtr object provides the capability to set and/or retrieve a pointer to the format array in the remote server control structure. The ManageFmtPtr object accepts the following input parameters: srvProcPtr--A pointer to the thread control structure action--An integer value that specifies whether to get the format pointer, set the format pointer or clear and release all allocated format structures type--An integer value that indicate whether to process a regular row format pointer or a compute row format pointer. computeId--an integer value that contains a compute identification of the format array which is returned to the calling object. fmtCtlPtr--A pointer to the format control structure fmtPtrPtr--An address to a pointer to the data format structure. The ManageFmtPtr provides no information to standard output or the DDS Error Handler. The ManageFmtPtr returns CS.sub.-- SUCCEED. Pass Results The PassResults object receives RPC command results from the data server and passes the data packets directly through to the requesting client object without disturbing the TDS packet. The PassResults object accepts the following input parameters: srvProcPtr--A pointer to the thread control structure. cmdPtr--A pointer to the command control structure. The PassResults object provides no information to standard output or the DDS Error Handler. The PassResults object returns CS.sub.-- SUCCEED or CS.sub.-- FAIL. Process Status Message The ProcStatusMsg object reads the return status code from a remote data server and returns the status to the client. The calling object is responsible for sending the serve send done to the client. The ProcStatusMsg object accepts the following input parameters: srvProcPtr--A pointer to the thread control structure. cmdPtr--A pointer to the command control structure. The ProcStatusMsg object provides no information to standard output or the DDS Error Handler. The ProcStatusMsg object returns CS.sub.-- SUCCEED or CS.sub.-- FAIL. Send Results The SendResults object processes data server(s) result sets that satisfy a client's request from one or more remote data servers. The calling object is responsible for sending the client the appropriate Serve MORE and the final Send Done to the client depending on the completion level of the client request. The SendResults object accepts the following input parameters: srvProcPtr--A pointer to the thread control structure. cmdPtr--A pointer to the command control structure. cmdType--An integer representing the command type, CS.sub.-- RPC.sub.-- CMD. fintCtlPtr--A pointer to the format control structure. The SendResults object provides no information to standard output or the DDS Error Handler. The SendResults object returns an integer -1 when an error condition exists or the number of rows processed. DDS Registered Procedures Several registered procedures have been developed to support administrative functionality for the DDS Open Servers. Open Server Shutdown Features The shutdown registered procedure, OsShutdown, provides a system administration tool that gracefully shuts down an open server application. A password is required from the command line to shutdown the open server. The OsShutdown registered procedure checks for any active RPC requests running against the DDS and returns control back to the systems administrator without shutting down the Open Server. An active RPC request is defined as a client issuing an RPC request for service through a DDS. If there are no active RPC requests, the OsShutdown registered procedure initiates the shut down of the specified DDS. The registered procedure accesses a globally defined DDS server table to obtain the valid password for the specified. DDS and validates the password against the SA provided password. If the password is valid, the registered procedure issues a stop event that shuts down the Open Server. If the password is invalid, a message is logged to the error handler and returns control to the SA without printing a message to standard output. Upon receiving the shutdown request, the registered procedure locks out any additional client request connections into the DDS Open Server application. Monitor Log Feature The monitor log registered procedure provides a mechanism that allows a client application to monitor the error and informational data being displayed in the DDS. The registered procedure, rp.sub.-- mon.sub.-- log,--log, allows a client application to make a request to a DDS Open Server to monitor the log file activity of the specified DDS. The registered procedure utilizes several error handler member functions to determine if any other user is monitoring the log activity, to register the requesting client thread with exclusive access to the monitoring functionality and a means to relinquish control of the monitoring functionality. The registered procedure call requires a valid password for the DDS and a time slice (in seconds) to monitor log activity. The log monitoring functionality permits only a single client thread to access the monitoring functionality at any given time and relinquishes control of the monitoring functionality when their time slice has expired. The client application can interrupt the monitoring activity I)y dropping their connection to the DDS Open Server. Monitor RPC Performance Registered Procedure The monitor RPC performance registered procedure provides a mechanism whereby a client application can monitor RPC performance either near real-time or historically. The two different types of monitoring can be initiated using Sybase-RPC's. The registered procedure will do near realtime reporting of RPC execution times when the @rpcoption parameter is equal to the string "ALL" or is a string containing a list of RPC's to be monitored. "ALL" is the default behavior for @rpcoption, so it need not be passed as an argument. The procedure will return to the monitoring client the RPC name, RPC client spid, and the RPC's execution time for a duration of num.sub.-- seconds. Because all of this RPC information is being passed to rp.sub.-- mon rpc via a message queues, only 1 near real-time monitoring session may run at a time. The actual processing of the RPC information for near real-time monitoring is performed by the global MonRPCMsgQ object named G.sub.-- monRPCMsgQ which is intanitated prior to the srv.sub.-- runO for the DDS. The RPC handler instantiates a MonRPC object each time an RPC is being run, and a pointer to that object is what is put on the queue when the near real-time monitoring is active and the RPC is one being monitored. The activation and polling of the message queue as well as the sending of results is all performed by G.sub.-- monRPCMsgQ.fwdarw.RunMsgQO. The cumulative average monitor can be run by more than one monitoring client at a time because it merely parses and orders information contained in the global Xrefdatatbl procList. All this processing is performed by a TopRPCList object. This registered procedure ensures that the number of elements in the top list does not exceed the number of elements in the proclist so that no memory is wasted. All the processing needed to return result rows to the client is contained in the TopRPCList object's member functions. The client will receive rows containing the RPC name, the cumulative number of executions of the RPC, and the average execution time for the RPC. The only argument to the rp.sub.-- mon.sub.-- rpcO function is the SRV.sub.-- PROC*, which is needed by the G.sub.-- monRPCMsgQ.fwdarw.RunMsgQO for activating the message queue and ensuring only one monitor is polling the message queue at a time. Both G.sub.-- monRPCMsgQ.fwdarw.RunMsgQO and the TopRPCList constructor need the SRV.sub.-- PROC* to be able to send result rows and messages back to the monitoring client. A set of data flat files is maintained to support the non-database related data needed by the DDS. A discussion of each of these files as well as their purpose and structure follows. Data Server Name File Definition The server name file, servers.dat, is used to store all of the available Data Server names that support the SMS. The DDS extracts the server names from this file and builds internal tables for quick delivery of server names to the requesting code. The server name data file contains three attributes, the Server Names, the system administrator's ID, and a password. Each type of server is separated by a Server Type identifier. The Server attributes and the Server Type identifier must be logically grouped together within the file. The password attribute is used to shut down the Open Servers in a graceful manner. DDS Configuration File Definition The DDS Configuration file contains configuration information that is used by the open server to set the Open Server properties on the startup of the DDS Open Server. The configuration parameters are specified in the file. Stored Procedure Requirements The following stored procedures are required to retrieve the data from the Xref Server. The data returned is used to populate the appropriate Xref data tables.
______________________________________
Stored Procedure Name - LP.sub.-- GET.sub.-- PROC.sub.-- LIST - Retrieves
a list
of procedure names and related information.
Logical Table Name - procedure.sub.-- list
Location - XRef Server
Procedure Type - Group
Database - xref
Input Parameters - Nothing or a valid stored procedure name
Output Values - A list of the attributes of the store procedure(s)
Procedure Text - As follows:
create procedure lp.sub.-- get.sub.-- proc.sub.-- list@pname char(30) =
"%"
as
begin
select procedure.sub.-- name,
group.sub.-- name,
procedure.sub.-- type,
dtp.sub.-- code,
argument.sub.-- position,
rule.sub.-- name,
server.sub.-- name,
database.sub.-- name
from procedure list
where procedure.sub.-- name like @pname
sort by procedure.sub.-- name
end
Stored Procedure Name - LP.sub.-- GET.sub.-- RULE.sub.-- LIST -
Retrieves a list of rule names and related information.
Logical Table Names - rule.sub.-- boundary and server.sub.-- list
Location - XRef Server
Procedure Type - Group
Database - xref
Input Parameters - Nothing or a valid rule name
Output Values - A list of the attributes of the store procedure(s)
Procedure Text - As follows:
create procedure lp.sub.-- get.sub.-- rule.sub.-- list @rule.sub.-- name
char(30) = "%"
as
begin
select rule.sub.-- name,
low.sub.-- value,
high.sub.-- value,
r.server.sub.-- name
from rule.sub.-- boundary r, server.sub.-- lists
where r.server.sub.-- name = s.server.sub.-- name
and
rule.sub.-- name like @rule.sub.-- name
sort by rule.sub.-- name, low.sub.-- value
end
Procedure Name - LP.sub.-- GET.sub.-- SEV.sub.-- LIST - Retrieves a list
of server
names and related information.
Logical Table Name - server.sub.-- list and server.sub.-- group
Location - XRef Server
Procedure Type - Group
Database - xref
Input Parameters - Nothing or a valid stored procedure name
Output Values - A list of the attributes of the store procedure(s)
Procedure Text - As follows:
create procedure lp.sub.-- get.sub.-- server.sub.-- list @sname char(30)
= "%"
as
begin
select server.sub.-- name,
warm.sub.-- server,
s.group.sub.-- name
from server.sub.-- list s, server.sub.-- group sg
where s.group.sub.-- name = sg.group.sub.-- name
and
s.server.sub.-- name like @sname
sort by s.group.sub.-- name, s.server.sub.-- name
end
LP.sub.-- GET.sub.-- PROC.sub.-- COUNT - Retrieves a count of the number
of
procedures
stored on the XRef Database.
Logical Table Name - procedure.sub.-- list
Location - XRef Server
Procedure Type - Group
Database - xref
Input Parameters - Nothing
Output Values - A count of all the store procedures
Procedure Text - As follows:
create procedure lp.sub.-- get.sub.-- proc.sub.-- cnt
as
begin
select count(*)
from procedure.sub.-- list
end
LP-GET.sub.-- RULE.sub.-- COUNT - Retrieves a count of the number of
rules
stored on the XREF Database.
Logical Table Name -server.sub.-- list and rule.sub.-- boundary
Location - XRef Server
Procedure Type - Group
Database - xref
Input Parameters - Nothing
Output Values - A count of all the rules
Procedure Text - As follows:
create procedure lp.sub.-- get.sub.-- rule.sub.-- count
as
begin
select count(*)
from rule.sub.-- boundary r, server.sub.-- list s
where r.server.sub.-- name = s.server.sub.-- name
end
LP.sub.-- GET.sub.-- SERVER.sub.-- COUNT - Retrieves a count of the
number of servers
stored on the XRef Database.
Logical Table Name - server.sub.-- list and server.sub.-- group
Location - XRef Server
Procedure Type - Group
Database - xref
Input Parameters - Nothing
Output Values - A count of all the servers
Procedure Text - As follows:
create procedure lp.sub.-- get.sub.-- server.sub.-- count
as
begin
select count(*)
from server.sub.-- list s, server.sub.-- group sg
where s.group.sub.-- name = sg.group.sub.-- name
end
LP.sub.-- GET.sub.-- SRVGRP-COUNT-Retrieves a count of the number of
server
groups stored on the XRef Database.
Logical Table Name - server-group
Location - XRef Server
Procedure Type - Group
Database - xref
Input Parameters - Nothing
Output Values - A count of all the server groups
Procedure Text - As follows:
create procedure lp.sub.-- get.sub.-- srvgrp.sub.-- count
as
begin
select count(*)
from server.sub.-- group
end
______________________________________
EXAMPLE Next discussed is a specific example of one possible implementation of the current invention. In the following discussion, it is assumed that the invention operates in a billing environment whereby customer account information may be updated and/or queried. It is to be understood that the example is but one of numerous applications whereby the benefits of the architecture and functionality of the current invention may be exploited. FIG. 5 shows three servers and a sample of records contained on each. It is to be understood that in a typical implementation there will be a large number of records on each of the servers. In addition, while the figure shows customer, product and promotion records, it is certainly possible to include other record types such as, for example, records related to operator statistics, marketing information, pay per view usage and availability, customer feedback and the like. In the example, Server A contains two customer records (one for Joe Smith and one for Red Purcell), a product record and a promotions record. Server B contains two more customer records as well as the same product and promotions records as contained on Server A. As described above, the customer records, in the preferred embodiment, are distributed horizontally and the product and promotion records are distributed vertically. Finally, on Server C. there are two more customer records and, again, the same product and promotion records as those contained on Servers A and B. The customer records in FIG. 5 contain various information about the customer and his or her account. In a typical implementation, there would be much more data. In the example, the first item listed is a customer number. In the preferred embodiment, each customer record corresponds to a unique customer number. Next, the customer name is listed followed by the customer's birthdate. Also included is the customer's telephone number, the services subscribed to, and any recent pay per view activity as well as the associated cost. Finally, a code for the cable operator location for the subscriber is included. In the first example, it is assumed that a customer service representative wishes to determine the current monthly payment for Joe Smith. The CSR, sitting at a transaction generator, would enter the name Joe Smith and a query for the monthly payment. In the operation of the SMS system, the request would be sent to the DDS through the use of a stored procedure. For example, the stored procedure for retrieving an account balance may be SPI. This stored procedure requires an argument specifying the customer number so that the correct record may be queried. Since all that is known is the last name of the customer, a prior query locating the customer number for the customer would be performed first. Once the customer number is returned and available to the client, the stored procedure SP1 with the customer number as an argument is transmitted to the DDS. In this case, the associated account number for Joe Smith is 100014. Thus, the client would submit the following stored procedure request to the DDS: SP1 100014 In one embodiment of the present invention a call to an XREF Server would be made to determine the particular server containing the record for the proper Joe Smith. In this case, the result set from the XREF Server would specify that the desired record is contained on Server A. In a second embodiment, the DDS itself maintains one or more internal tables which indicate, based upon a particular customer number, the server containing the associated data. In either case, the stored procedure is translated at the DDS level into SQL commands recognizable to the data servers containing the data. In the example, the command stream generated by the DDS is transmitted to Server A which executes the commands and returns the record for Joe Smith through the DDS, in passthrough mode, to the requesting client. The record, including the monthly payment, is then displayed in an easily readable format at the CSR's terminal. The data request described above is termed SPECIFIC request. This means that the data requested is contained only on a particular server and that server must be used in the execution of the query. As a second example, suppose that an administrator, operating at a CSR terminal, wishes to review the various HBO offerings in the system. As described above, the BOS34A operator's HBO product is contained upon each of the servers in the system. In addition, although not shown, various other operator's HBO products would also be distributed over each of the servers. Thus, the requested data may be processed according to an ANY request. In this case the stored procedure may be SP2 with an argument of HBO. In this example, once the DDS associates SP2 as a stored procedure that may be executed as an ANY request, it selects any one of the servers. The server may be selected either at random or according to any particular scheme known in the art (i.e. determining the least busy server). Another example may be a request by an administrator for all customers that are served by the AZ67E cable operator. In this example, these customer records are distributed over two of the servers (Server A and Server C) and in practice, the records could potentially be contained on any of the servers. Thus, all of the servers must be queried for this type of request. As such, this type of request is termed an ALL request. In this case, assuming the stored procedure for retrieving each of the customer records matching a particular characteristic (e.g. AZ67E operator), is SP3, the request would be: SP3 AZ67E the argument AZ67E referring to the cable operator serving the customer. The DDS would process this stored procedure by sending the appropriate SQL commands to each of the servers in turn (or in parallel), collating the results and returning the ultimate result set to the requesting client. The above examples are all query (read) examples. As an example of an update request, suppose an administrator wishes to add a new promotion to the SMS system. Further, suppose he or she desires to add the ESPN record shown in FIG. 5 to all of the data servers. In this case, the client sends an SP4 stored procedure request as follows: SP4 Promotion ESPN FREE.sub.-- INSTALL The DDS will then cause each of the servers, through an ALL request, to add the new promotion. The FREE.sub.-- INSTALL argument will necessarily pass information associated with the particular promotion. For example and in this case, the order date and the participating operator will be specified. Alternatively, the promotion record may be placed upon all SMS servers by performing an ALL request and then replicating the record throughout the system as part of a background task. In a preferred embodiment of this alternative, the ANY request will be directed to the "primary server" which will replicate the information. A method and apparatus for achieving high transaction rates in a distributed database environment has been described above. As a result of such description, the advantages of the present invention will be apparent to those skilled in the art. While the invention has been described in conjunction with preferred embodiments, it is evident that numerous alternatives, modifications, variations and uses will be apparent to those skilled in the art in light of the foregoing description.
|
Same subclass Same class Consider this |
||||||||||
