![]() | Programming Guide | ![]() |
Initiates a service call from a client agent
service_callserviceName([requestMsg] [[,]replyMsg])
[callOption]...
serviceName- Any JIF-defined service, specified as a variable or quoted string. The service name can be up to 15 characters long.
requestMsg- Message data supplied by this client to the server, where
requestMsg's data type is defined in the JIF's definition of this service. For more information on message data types, refer to "Service Messages and Data Types" in JetNet/Oracle Tuxedo Guide.replyMsg- Specifies the variables to receive the data that the service returns to the client. The format of the return data is specified in the JIF's definition of the service. If the service call also specifies request message data, separate the two messages with a comma. For more information on message data types, refer to "Service Messages and Data Types" in JetNet/Oracle Tuxedo Guide.
callOption- One or more options that control service call behavior. Each call option can be set through the service's JIF definition; unless the command specifies otherwise, the service call uses the JIF settings.
service_callcall options always have precedence over their corresponding JIF settings. You set call options through these key words:
ASYNC- Specifies to let the client resume processing immediately after issuing the call without waiting for a response. If you omit this option, all processing on the client is suspended until the service call returns.
NOTIMEOUT- If service calls are blocked (the
tp_blockproperty is set to Yes), this option overrides the blocking timeout and blocks the call indefinitely.NOREPLY- Use only in
ASYNCmode to inform Panther that this service call expects no reply, so there is no need to poll for one.Note: From the client's perspective, Panther makes no attempt to poll for a reply or to receive one; however, Panther might quietly poll for a reply if required by the middleware to end the client-server connection.
The following restrictions apply to the use of
NOREPLY:
- (Oracle Tuxedo only) The
NOREPLYoption cannot be used with a service request that is part of a transaction. To remove a service request from an active transaction use theOUTSIDE_TRANSACTIONoption.OUTSIDE_TRANSACTION(Oracle Tuxedo only)- Specifies to execute the service call independently of the active transaction, if one exists. Use this option in order to prevent events generated by this request from being affected by commits or rollbacks of the current transaction. If you specify this option, transaction-level exception and unload handlers are not executed when their corresponding events are generated.
EXCEPTION_HANDLERhandler- Specifies an exception handler to install at the request scope, where handler is a Panther variable or a string. This handler handles any exceptions that result from the request or its response.
The handler is installed just before service invocation, that is, after all parsing, interpretation, and validation of the command has occurred. For more information on exception events and handlers, refer to "Exception Handlers"in JetNet/Oracle Tuxedo Guide.
UNLOAD_HANDLERhandler- Specifies an unload handler to install at the request scope, where handler is a Panther variable or a string. This handler handles any unload events that might result from receiving the service's response. The service must be called synchronously (without the
ASYNCoption).The handler is installed just before service invocation. For more information on unload events and handlers, refer to "Unload Handlers" in JetNet/Oracle Tuxedo Guide.
PRIORITYpriority- A signed or unsigned integer that sets the priority for
serviceName. If unsigned, priority overrides this service's predefined priority; if signed, priority is added or subtracted from the predefined priority. In both cases, a service's priority level must be between 1 and 100. If you omit this option, the middleware uses the priority that is set in the JIF or (under Oracle Tuxedo), in theTUXCONFIGconfiguration file.
JetNet, Oracle Tuxedo
Client, Server
The
service_callcommand invokes a service request that can be issued by a client or a server. A server that requests a service acts in the role of a client. The JIF is accessed at runtime to determine predefined service attributes such as message data type.
service_callcan specify zero to two messages that enable exchange of data between the calling client and the server that processes the requested service. Depending on how the JIF defines the service's transport method, message data can have one of these forms:
- ()—No data sent or received.
The JIF also defines each message's data type. For more information, refer to "Service Messages and Data Types"in JetNet/Oracle Tuxedo Guide.
If the JIF defines a service to use the transaction manager, any data that the transaction manager needs for a database operation or that it returns is automatically appended to the corresponding request or reply message. For example, service
customer_sspecifiesSelectas its transaction type. When that service is called, the middleware appends to the request message any data that the transaction manager needs to construct aSELECTstatement. When the service returns, the middleware appends the query results to the reply message.When
service_callcalls a service that uses the transaction manager, the command must always specify one or both messages, according to the transaction's type. Thus, a service that specifiesSelectas its transaction type must be called with both messages; a service definition that specifiesDeleteas its transaction type can be called with only a single (request) message.If a
service_callcommand has no message data of its own, the command must use the default mapping format for one or both messages:{...}. For example, aservice_callcommand can invoke thecustomer_sservice as follows:service_call "customer_s" ({...}, {...})
By default, a service call is issued in synchronous mode—that is, processing on the client is suspended until it receives a reply from the service. You can specify asynchronous mode for a service call through the
ASYNCoption. In this case, client processing continues without waiting for a response from the service.Asynchronous processing might be desired if a client transaction includes several service calls that can be executed simultaneously. For example, a bank account transfer procedure requiring a debit to one account and a credit to another might be performed simultaneously as one transaction. If there is an error in the execution of one service, the entire transaction can be rolled back (Oracle Tuxedo only).
Asynchronous service calls can be issued by clients and servers, with these differences:
- For clients, Panther polls continuously for a reply from the service. This guarantees that requested data is returned when the service completes.
When a client agent initiates a service call, events are raised depending on the
service_calloptions used. Figure 2-1 shows the sequence of events as the service call is processed.![]()
Figure 2-1 Event stream generated by a service_call
Refer to Chapter 6, "JetNet/Oracle Tuxedo Event Processing," in JetNet/Oracle Tuxedo Guide for information on middleware-related events, and how handlers can be used to customize your application's response to specific service calls.
The following scenarios illustrate a variety of ways of using
service_call:
If service
INQUIRYis defined in the JIF to allow only incomingJAMFLEXdata, you can pass the string"Brontis"to the service as follows:service_call "INQUIRY" ({"Brontis"})The following code calls the same service in asynchronous mode, passing the content of variable
nameto the service:service_call "INQUIRY" ({name}) ASYNC
If service
GET_NAMEis defined in the JIF to allow only outgoingJAMFLEXdata, you can designate variablenameto receive string data from the service as follows:service_call "GET_NAME" ({name})This code also calls the
GET_NAMEservice, this time specifying an unload handler (name_unload) to unload the data:service_call "GET_NAME" ({name}) UNLOAD_HANDLER "name_unload"
The four examples illustrate how the service
DEPOSITis called. The service can be defined in the JIF to useJAMFLEXbuffer types for messages.
- Call the
DEPOSITservice and designate the content of the variablesACCOUNT_IDandAMOUNTasINparameters, and designate the content ofMESSAGEandACCOUNT_BALas the data to receive back from the service:
service_call "DEPOSIT" ({ACCOUNT_ID, AMOUNT},\
{MESSAGE, ACCOUNT_BAL})- Call the
DEPOSITservice and map local variable id toACCOUNT_IDand local variableamttoAMOUNTin asynchronous mode with theNOREPLYoption:
service_call "DEPOSIT" ({ACCOUNT_ID=id, AMOUNT=amt})\
ASYNC NOREPLY- Call the
DEPOSITservice and map the local variable id toACCOUNT_IDand local variableamttoAMOUNT, and map the receivingMESSAGEinto the local variable msg, andACCOUNT_BALinto the local variablebal:
service_call "DEPOSIT" ({ACCOUNT_ID=id, AMOUNT=amt},\
{MESSAGE=msg, ACCOUNT_BAL=bal})- Call the
DEPOSITservice with a relative priority of +50:
service_call "DEPOSIT" PRIORITY +50 \
({ACCOUNT_ID, AMOUNT},{MESSAGE, ACCOUNT_BAL})
Under Oracle Tuxedo, the same service can be defined to use FML buffer types. This requires that the FML file contain the following entries for FML fields for the
bankappdatabase:
Name Number Type Comments
ACCOUNT_ID101
long
Account No.
ACCOUNT_BAL117
float
Account balance
AMOUNT111
float
Transaction amount
MESSAGE126
string
Message text
The screen variables have identical names to the FML fields.
Table 2-1 shows which application properties are affected when
service_callexecutes:
service_callcan generate the following exceptions:
The following procedure
init_atminitiates the client identification process when a user logs on as an ATM customer. FML buffers are used in a call to theVAL_PINservice. For the server end of this process, refer to the receive command.proc init_atm ()
vars message...
@app()->hdl_exception = "exc_hand"
@app()->hdl_jif_changed = "jchhandc"client_init client last_name user "Customer" \
notification poll
if ((@app()->tp_severity) > TP_WARNING)
{
// initiating a connection was unsuccessful
message = @app()->tp_exc_msg
msg quiet message
...
return 0
}
// validate PIN given by the customer
service_call service "VAL_PIN" ({last_name, pin}, \
{message, owner_ssn = user_info})
// check if validation was not successful
if ((@app()->tp_severity > TP_WARNING) || \
(@app()->tp_svc_outcome == TP_FAILURE))
{
msg quiet message
client_exit
...
}
...
return 0
}
receive, service_cancel, service_forward, wait
![]()
![]()
![]()
![]()