Skip Headers

Oracle9iAS Containers for J2EE Enterprise JavaBeans Developer's Guide
Release 2 (9.0.3)

Part Number A97677-01
Go To Core Documentation
Core
Go To Platform Documentation
Platform
Go To Table Of Contents
Contents
Go To Index
Index

Go to previous page Go to next page

10
Active Components for Java

Active Components for Java (AC4J) enables applications to interact as peers in a loosely coupled manner. Two or more applications participating in a business interaction exchange information for the purpose of requesting service and responding with results.

This document describes software Oracle provides to manage loosely coupled interactions between autonomous applications. It also discusses the architecture necessary to run the software.

Future Needs of Business Applications

The future of business applications requires the ability to perform loosely coupled interactions. That is, applications should be able to exchange information with other applications over a long period of time, without limiting resources, and by surviving system crashes. Loosely coupled interactions have the following requirements:

  1. Autonomous peer--Each application, when interacting with another application, exists as an autonomous peer. That is, the responding application can choose to ignore the request, or to execute one or more functions on behalf of the requester (possibly different from the one that the requester asked for), before responding to the initiating application. As peers, both applications can make requests to each other, but neither can require submission from the other. Neither application can assume control over the resources that its peer application owns.

  2. No time constraints--Because the tasks that are performed sometimes take days, even months, to complete, there must be no time limits imposed.

  3. Asynchronous exchange of information--Loosely coupled interactions require that all exchange of information exists within an asynchronous environment. The inter-peer interaction performs one of the following:

    • Distribute information interaction--Sometimes an application must be able to distribute information asynchronously to its peer where no response is required. However, reliability of the delivery for this message must be ensured.

    • Request or respond to interaction between components in an asynchronous manner--Applications use a request and response mode of communication, in which each entity knows where to respond with the results.

  4. Reliability--For any application to exist over a period of time, the application must be reliable; that is, recoverable and restartable, in case of system failures during that time.

  5. Scalability--The application must be scalable; that is, a long-running application cannot block execution or lock resources for long periods of time. For the application to execute in a reasonable time frame, the framework must provide performance enhancements through concurrently executing computations.

  6. Monitoring ability--The application must be able to define and track its business processes and their interaction patterns, including the following:

    • What business processes have started or completed under what business conditions

    • What business processes are pending, and waiting for what business documents

    • What the pattern of interaction of the business processes is, where processes can exchange information, and what information they are authorized to push to or pull from other processes

    • What the sequencing of execution of the defined processes is

Architectures

Until AC4J, the following two architectures were available:

The following sections briefly describe these models and show why they do not offer the basis necessary for the six goals presented in "Future Needs of Business Applications". After the two architectures are described, AC4J is shown to be not just a new technology, but one that builds on the two architectures, eliminating their negatives and drawing on their positives. AC4J has the look and feel of Remote Procedure Call and database queueing, which it uses as building blocks.

Remote Procedure Call Model

One of the building blocks of AC4J, the Remote Procedure Call (RPC) programming model, facilitates a tightly coupled environment that provides for request-response communication. Transactional RPC implementations provide for ACID (atomicity, consistency, isolation, and durability) qualities.

Most RPC implementations currently provide two modes of method invocations: synchronous and deferred synchronous.

Transactional RPC Synchronous Invocation

The client program blocks when a remote invocation is made, and waits until the results arrive or an exception is thrown. Examples of application types that use transactional RPC implementations are EJB and most CORBA applications. Web services are also based on the RPC model, but are not transactional.

Advantage

This model of communication--also known as online or connected--is based on the request-response paradigm, in which the requester and responder of the service are tightly coupled. Tightly coupled applications understand how to reply transparently to the requester.

Disadvantage

The programs must be available and running for the application to work. In the event of a network or system failure, or when the application providing the service is busy, the application is not able to continue forward with its processing work. In this case, the state is inconsistent and the application must roll back to a consistent state through JTA (Java Transaction API). In addition, the application is not autonomous. One application can control resources of other applications for a long time.

JTA is based on the two-phase commit specification. The two-phase commit protocol can cause loss of application autonomy in the case of network disconnection, where the coordinator is incapable of making a coherent global decision over the outcome of the global transaction for a long period of time.

Example

If a purchase order is created and the customer wants to purchase 20 widgets, then the transactional RPC application must do two things:

In this example, an RPC synchronous application would (within a global transaction) do the following:

If both requests come back with a satisfactory report, then the transaction is committed, and the purchase order is forwarded on to shipping. If one of the two requests fails, the transaction is rolled back; of course, to prevent rollback, the application could perform the following alternatives:

If the transaction is rolled back, the purchase order is voided (unless one of the alternatives is performed).

RPC Deferred Synchronous Invocation

An RPC-deferred synchronous invocation is queue-oriented. The client places a request in a queue and is then able to continue processing without blocking for the response. An example of this is a CORBA DII (Dynamic Invocation Interface) application.

Advantages

The client does not need to wait for a reply to the request. Instead, the client continues processing. Then when the client wants to receive a response, it blocks or polls for the availability of the response. A response can be delivered only to the same process that made the original deferred request. Thus, if multiple deferred requests are pending, only one response is processed at a time.

Disadvantage

If the client is nonexistent, then the response is lost. Thus, for deferred execution to work correctly in the presence of network, system, and application failures, the requests must be stored persistently and processed exactly once.

Example

In the purchase order example, the requests to the inventory and credit bureau can be made in parallel. After executing both requests, the client can poll for both responses. The disadvantages are the same as listed within the RPC synchronous invocation example.

Database Transactional Queueing Model

Another of the building blocks, the database transactional queueing model, supports a loosely coupled environment where applications use one-way communication. Oracle AQ is an implementation of a database transactional queueing model.

Applications need to process and deliver each message exactly once, even in the presence of multiple failures of the sender or the receiver. Mixing the transactional ACID construct with queue processing creates a model that enables applications to reliably process messages with the ACID guarantees.

Applications can be disconnected for long periods of time, and occasionally they can reconnect to communicate, using messages. By decoupling the applications that send messages from the applications that receive messages and process them, queueing facilitates complex scheduling of autonomous applications. Each message can be durably saved until processed exactly once. Processing of the data is performed in a time-independent fashion, even in a situation in which a message receiver is temporarily unavailable.

Advantage

Delivers and processes messages exactly once, no matter whether the network or receiver application is available.

Disadvantage

This model is based on sending and receiving messages, not on requesting and responding to service requests. Sending and receiving messages is the foundation of all business protocols for loosely coupled applications. To satisfy this requirement, the application is responsible for creating and parsing each message. Both sides must know the format, security, and headers required for each message. There is no automatic mechanism for routing messages and executing business methods. The implementation of application logic for these mechanisms is the responsibility of the applications. If a response is called for, the application cannot easily reply, because there is no context that captures the relationship between a requester and a responder application; this is not true for RPC. This model is not intended for a request-response environment, so if the client needs a response back from the destination object, it must receive and parse a separate message off of its own queue.

Exception handling describes communication failures--not application exceptions.

There is no guarantee for the consistency of the business transactions. Instead, the program itself must guarantee that the application semantic rollbacks (semantics of undoing a process but not necessarily restoring the original state) occur appropriately in a failure situation.

Example

In the purchase order example, the client would enqueue a message to the inventory queue and another to the credit bureau queue. Both must be reliably processed once for the transaction to commit. If either the inventory is not available or the client's credit is not good, the business transaction cannot be successfully completed, and another message must be created to semantically roll back the one message that was processed positively.

AC4J Solution

The RPC and transactional database queueing models both have advantages and disadvantages. The disadvantages keep them from being the best solution. The disadvantages within J2EE application types, and the reasons that previous methods did not work, are as follows:

The disadvantages prevent each model from solving the business goals laid out in "Future Needs of Business Applications". Thus, a new model is necessary to incorporate the advantages of both models and exclude the disadvantages.

Arising out of and building upon the previous two models, AC4J is a manager of loosely coupled interactions between autonomous EJB applications. You can partition the application into concurrently executing active units of work--known as reactions--whose execution is driven by data availability, and its purpose is to execute business logic and produce new data. AC4J coordinates the flow of data between reactions. When data become available on AC4J, the conditions specified by all registered reactions are checked and, if satisfied, then the execution of the methods of all matched reactions is triggered.

AC4J Architecture

AC4J allows EJBs to interact in a loosely coupled fashion. It provides the following features:

Introduction to AC4J Components

AC4J provides a framework for loosely coupled interactions, which are included in the following components, each described more fully after this section:

Figure 10-1 demonstrates the relationship of these components to each other. The sections following (up to, but not including, "Configuring Oracle Databases to Support AC4J") describe each component.

Figure 10-1 AC4J Relationship Diagram

Text description of ac4j4.gif follows

Text description of the illustration ac4j4.gif

Active EJBs

An EJB provides a natural way for describing a business object--such as a customer, purchase order, or invoice. The externally visible business tasks of a business object, which is accessible by other applications, are separated from their internal implementation details and are described in the EJB interface.

Traditional EJBs are passive: they must be ready to immediately service a request from a client and return results quickly. Failure to deliver on these promises causes an EJB to be unusable. AC4J allows standard stateless session and entity EJBs to become active. Active EJBs permit requests for service to be decoupled from the actual service execution. The policies that control when and which EJB methods are actually invoked are controlled by the service provider EJB. This de-coupling permits service request and service providers to interact as autonomous peers.

An application can create or look up a JEMHandle and then request service from a business task, which is exposed in the EJB interface.

An Active EJB is uniquely identified by a JEMHandle object. A JEMHandle object encapsulates the following:

Interaction

An interaction is a long-lived unit of work that reflects the behavior of a business transaction. A business transaction can span multiple applications that reside in different organizations. Contrary to the life of a local or a global transaction, the duration of these business transactions in this disconnected environment can be long.

The interaction represents a business goal that you want to complete. For example, if a customer wants to buy something from a business, all the actions necessary to allow the customer to pay for and receive the item he wants is characterized as an interaction. The interaction groups a series of business data exchanges by providing the global execution context of the business transaction.

These applications can run in isolation and commit or roll back their own data without knowledge of other applications. However, these applications should not be considered as different pieces, because the relationships formed among them must be coordinated and their consistency maintained. When a business transaction becomes inconsistent, its participating applications may need to recover. The application recovery can be obtained by registering compensating reactions. For example, when the supplier has confirmed the purchase order request back to the buyer, the buyer must register a compensating reaction that monitors additional responses from the supplier that may inform him that, for example, the purchase order cannot be fulfilled because the manufacturing department is running late. If the supplier's confirmation of the request is cancelled, then the buyer's compensating reaction is matched and then fired to allow the buyer application to recover its application consistency. This reaction can pick a new supplier and request the item from the supplier or abandon the purchase order process completely.

An interaction is uniquely identified by an interaction identifier (IID). An interaction can contain multiple processes.

Processes

A process identifies a business task. In our purchase order example, a process exists for each of the following business tasks: creating a purchase order, checking inventory, checking customer credit, and shipping the order.

Each process does the following:

Figure 10-2 demonstrates an Active EJB, an interaction, and two of its processes.

Figure 10-2 Relationship of Active EJB, Interaction, and Processes

Text description of ac4ja.gif follows

Text description of the illustration ac4ja.gif

A process is uniquely identified by a JEMPortHandle object, which encapsulates the process context and the JEMHandle of the Active EJB that the process belongs to. The process context is a union of an interaction identifier and the process activation identifier. AC4J automatically creates the interaction and process activation identifiers within a call operation. Alternatively, the application can supply them in the AC4J JEMSession::call operation.

Reactions

A reaction performs the detailed work of a process. Using this construct, an application can specify its persistence interest in the availability of a collection of correlated data tokens that trigger the execution of an Active EJB method. A reaction is a combination of the following:

When a process is created as the result of a AC4J call operation, AC4J implicitly creates a base reaction. Additionally, an application can explicitly create a reaction at run time, using the JEMReaction::registerReaction operation to synchronize on data tokens. The implicit or explicit registerReaction operation specifies the reaction template and the Active EJB method to be executed when matching succeeds.

Reactions (EJB methods) can access and modify shared database objects. These objects can be traditional database objects--thus, facilitating coarse grain information sharing in a transactional manner. Similarly, the reactions exchange fine grain information--such as Active EJB method input parameters and return values--using the AC4J data bus.

The reaction processes incoming requests, returns results based on the request, and enforces business constraints to preserve application consistency. When a reaction is fired, it can consume one or more input data parameters, process them, and then possibly produce one or more output data tokens for other reactions. Figure 10-3 illustrates how, when all data tokens are available and the conditions are matched, the reaction fires, which causes the method to execute. This method can return results that are converted to data tokens by the AC4J infrastructure and routed to the caller. This method can request additional services from other Active EJBs to complete the business task. These requests result in the creation of new data tokens, which are pushed and routed by the AC4J data bus.

Figure 10-3 Firing a Reaction

Text description of ac4j3.gif follows

Text description of the illustration ac4j3.gif

Reactions inside a process context instance can push data tokens to the AC4J data bus in the following ways:

Reactions inside a process context instance can pull data tokens from the AC4J data bus by registering one or more reactions in the current process context instance, using the JEMReaction::registerReaction method.

One or more reactions can exist for each business task. A reaction is used for the request and another for the response to support the asynchronous nature in a request-response environment. The number of reactions depends on the number of requests and responses necessary.

The following example demonstrates how one can receive an asynchronous communication between processes, but still have a request-response environment. The takeOrder process is the business task for creating the purchase order. To create the purchase order, you must check the inventory and the customer's credit. Thus, the takeOrder reaction invokes the following processes:

After sending the asynchronous requests to the checkINV and checkCRED processes, the takeOrder reaction registers another reaction in the same process--procPO--that waits for the responses back from both the checkCRED and checkINV processes. When all data tokens expected from these processes are available, the procPO reaction fires and processes the responses. As Figure 10-4 shows, both the takeOrder and procPO reactions exist in the same process, because they are components of the same request-response communication.

Figure 10-4 Relationship of JEMPurchaseOrderBean Interface Methods

Text description of ac4j5.gif follows

Text description of the illustration ac4j5.gif


Note:

To satisfy the AC4J requirement of not locking resources, the call should be an asynchronous AC4J call. However, you can still perform synchronous EJB calls to another bean.


Data Tokens

The activation of a reaction is triggered by the availability of data tokens. Availability is defined by the arrival of one or more data tokens, with the right conditions, and the right access mode.

When an application is requesting a service by using an AC4J call operation, the system automatically pushes a request data token, which comprises the following:

Later, when a reaction returns a response data token that is automatically generated by AC4J when an active EJB returns or throws an exception, AC4J fills in the routing information needed for sending the returned information to the caller process and fills the port handle object of the response data token. In the case in which the caller of the returning process is a client and not another process, then the data bus stores the response data token to a special data bus area from where the client can retrieve it, using the JEMSession::receiveReactionResponseObjectInstance operation.

The data types of the objects carried inside an input or output data token can be basic data types (such as integer, string, float, boolean) or constructed class types (such as Java serializable objects).

Data Bus

Improving the autonomy, scalability, and availability of applications requires components that are requesting services to be unaware of the identity, location, and number of components that provide these services. In AC4J, applications are attached to a data bus before starting their operation. The AC4J data bus is responsible for routing and matching data tokens that are pushed and must be pulled by registered reactions. Additionally, the data bus enables scheduling, activation, and execution of the matched reactions.

Matching Reactions

The data bus routing subsystem is responsible for making the different types of data tokens available at the specified destination, the process context instance that comprises the interaction identifier and the process activation identifier, specified by a JEMPortHandle object.

When data tokens are routed and become available in the data bus inside a process context instance, AC4J tries to match these data tokens with all registered reactions that are available in that context instance. The system tries to match the data token tags that are specified in a reaction template, evaluating all constraint conditions against the matched data tokens to filter and discard the inappropriate ones.

Availability of some data tokens does not mean that a registered reaction will match immediately. Only when all data tokens required by a reaction become available does matching succeed. For example, inside takeOrder process the takeOrder base reaction has registered the procPO reaction that is waiting for the checkCRED and checkINV processes to respond. When the checkINV process responds to the takeOrder process, the procPO reaction is not matched because it is also waiting for the checkCRED process to respond. When the checkCRED process responds to the takeOrder process, the procPO reaction is matched.

Additionally, data tokens that are available in the data bus can be matched with a reaction that will be registered in the future. This can be used for sequencing processes, where the completion of one process can enable another process. Inside the same interaction, the takeOrder process must be completed before the cancelOrder process can start executing. If the takeOrder process has not completed but the cancelOrder process is requested from a client, then its base reaction, which is implicitly created by the system, will not be matched, because it is waiting for the completion data token of the takeOrder process to be available. If the takeOrder process has completed (thus having already pushed its completion data token), then the cancelOrder process is requested from a client, and it will be immediately matched, because the completion data token of the takeOrder process is already available.

Matching data tokens with reactions triggers the activation of zero, one, or more reactions, which are executed in parallel if they do not conflict for shared resources.

Firing Reactions

Each method of the remote interface of an Active EJB implements the application business logic. When the data tokens become available, and are matched with a reaction, AC4J verifies that the types (primitive or class types) of the data tokens matched on the tags also match the types of the reaction Active EJB method types. Then AC4J verifies that the matched reaction is authorized to pull the available matched data tokens. If everything passes successfully, AC4J schedules the activation of the reaction.

When the matched reaction is fired, the AC4J container begins a JTA transaction and instantiates the requested Active EJB (stateless session bean or entity EJB) using the primary key inside the JEMHandle request object. Then the EJB method of the fired reaction, is executed using the matched data tokens of the reaction.

AC4J automatically commits the current reaction at the end of every Active EJB method. A reaction commit marks the end of a JTA transaction so that all its changes to shared data tokens, and all its service requests and responses that have been sent, become visible. The activation of a reaction has "exactly once" semantics (that is, the code specifies that it executes exactly once) if the reaction commits. If a failure occurs after a commit, then the reaction cannot be rolled back and the changes will persist. If a failure occurs before or during a commit, then the container rolls back the current reaction. A reaction rollback reverses all changes to shared data tokens, and the service requests and responses are never sent to any recipient component. In case of failures, the data bus will retry to fire the reaction for a preconfigured number of times. The reaction is marked as completed, with exception completion status if the maximum retry attempts are reached.

In traditional databases, where the duration of a transaction is short, abnormal situations cause the whole transaction to be undone, so all performed work is lost and must be submitted again for execution. Since interactions have usually long duration and contain a large number of reactions, AC4J provides additional mechanisms to handle exceptions (such as an Oracle9iAS node crash or an Oracle database node crash).

AC4j automatically makes a reaction persist in the data bus if it completes successfully. The state that is saved (process input variable data, process local variable data, and data flow context information) can be used to continue the application with minimum restart time from the last reaction. When a node crashes, all reactions that were running and did not end successfully are rolled back. AC4J then reexecutes the interrupted reactions in another OC4J instance.

AC4J uses a mechanism to capture, propagate, and match the application state and control flow information needed for resuming an application after the crash. Additionally, because reaction execution is data-driven, there is no need for the system to keep a volatile or persistent copy of the entire program state (such as program execution stack) to facilitate the storage of the control flow descriptors or the storage of data variables.

Relationships of Data Bus, Data Tokens, and Reactions

Figure 10-5 demonstrates how data tokens cause reactions to fire, and how reactions send new data tokens to other reactions over the data bus. The data bus coordinates and matches the data tokens with its reactions.

Figure 10-5 Data Bus, Data Tokens, and Reactions

Text description of ac4j6.gif follows

Text description of the illustration ac4j6.gif

After the method completes, the reaction sends information in the form of a data token to another reaction. All data tokens are sent asynchronously from one reaction to another over a data channel known as the AC4J data bus. The AC4J data bus routes the data tokens from a producer reaction to one or more consumer reactions.

Configuring Oracle Databases to Support AC4J

Before you can execute any interactions, you must initialize an Oracle9i database as a repository for the AC4J data bus. You must configure it to include the following:

You can add the elements of the preceding list to your Oracle9i database with scripts that are contained in the ac4j-sql.jar file that was downloaded with your Oracle9iAS installation. Unzip this JAR file, which contains a README.TXT file that discusses the different SQL command options that are available to you. These commands are also described in the following:

To create AC4J capabilities, you must execute one of the following SQL scripts as a SYS user on the same system as the database.

AC4J Data Bus XML Configuration

The interaction supports JTA global transactions within the database that the data bus exists in. Thus, you need a nonemulated data source for the superuser to handle the two-phase commit, and a nonemulated data source for the client to send its asynchronous requests to the data bus. See the DataSource and JTA Chapters in the Oracle9iAS Containers for J2EE Services Guide for a full description of this configuration.

For our purchase order example, the following data sources are configured in the data-sources.xml file for the two-phase commit.


<!--NON-Emulated DataSource for two-phase commit used by super user-->
<data-source
                class="com.evermind.sql.OrionCMTDataSource"
                location="jdbc/jemSuperuserDS"
                username="jemuser"
                password="jempasswd"
                url="jdbc:oracle:thin:@host:port:ORCL-SID"
                inactivity-timeout="60" >
                <property name="dblink"
                    value="JEMLOOPBACKLINK.REGRESS.RDBMS.DEV.US.ORACLE.COM" />
</data-source>

<!--NON-Emulated DataSource for the client user -->
<data-source
                class="com.evermind.sql.OrionCMTDataSource"
                location="jdbc/jemClientDS"
                username="jemcliuser"
                password="jemclipasswd" 
                url="jdbc:oracle:thin:@host:port:ORCL-SID"
                inactivity-timeout="60" >
                <property name="dblink"
                   value="JEMLOOPBACKLINK.REGRESS.RDBMS.DEV.US.ORACLE.COM" />
</data-source>

Both of these users were created as defaults with the SQL scripts listed earlier. The jemuser is the superuser username, and the jemcliuser is the default client username. The DBLINK is the link to the database that contains the data bus. For the superuser data source, the DBLINK is a loopback link.

AC4J Example

AC4J is designed for complex applications that interact with each other over long periods of time. This section illustrates the usage of AC4J with a portion of the purchase order example shown in Figure 10-6. To simplify the example, the code sample does not show error handling or import statements. Download the full example off the OTN site.

Example 10-1 Purchase Order Example

For the purchase order, the POInteraction is created. Within the interaction, several business tasks exist as follows:

The example includes the following:

Figure 10-6 illustrates the information flow inside an interaction. Figure 10-6 also demonstrates how all of the reactions act on data tokens and provide data tokens to other processes. This assumes that the customer data has already been made available to the takeOrder process. The numbers designate the order in which the reactions fire. That is, the procPO is dependent on data tokens from both the checkINV and checkCRED processes; thus, it cannot fire until both return their responses back to the takeOrder process.

Figure 10-6 Information Flow Inside An Interaction

Text description of ac4j2.gif follows

Text description of the illustration ac4j2.gif

Here is a summary of the steps in processing the Purchase Order example of Figure 10-6:

  1. Client sends an asynchronous request to an Active EJB: The client requests a service from an Active EJB, JEMPurchaseOrderBean. The client starts a new purchase order by sending an asynchronous request through the data bus (not shown) to a takeOrder process.

  2. Active EJB processes the client's request: The takeOrder process starts a takeOrder base reaction. This base reaction starts a new purchase order. To complete the purchase order, it must perform three things:

    1. Send an asynchronous request to the checkINV process of JEMInventoryBean to verify that the items are in inventory

    2. Send an asynchronous request to the checkCRED process of JEMCreditBean to verify that the customer's credit is satisfactory

    3. Register a procPO reaction in the current process to receive the results from the preceding two processes

  3. Asynchronous response to the requesting Active-EJB: Both the checkINV and checkCRED processes return responses to the takeOrder process.

  4. Asynchronous response to the client: The procPO reaction, within the takeOrder process, reacts to the information provided by the checkINV and checkCRED processes. If satisfactory, the procPO reaction sends the confirmation to the client through the AC4J data bus.

  5. Client receives the response: The client retrieves the response from the data bus.

Asynchronous Request to An Active EJB

The following code sample shows the steps in performing loosely coupled interactions in AC4J.

Example 10-2 Client Asynchronously Invoking Active EJB

public static void main(String[] args) throws  ClassNotFoundException, Exception
{

// 0. create a JNDI context
Context  context = new  InitialContext();

// 1. look up a datasource where Databus exists
DataSource clientDS = (DataSource)
                      context.lookup("java:comp/env/jdbc/jemClientDS");
// 2. Get a JDBC-connection to the database where Databus resides
Connection conn = clientDS.getConnection("jemcliuser", "jemclipasswd");

// 3. Create an AC4J connection using the JDBC connection
JEMConnection AC4JConn = new  JEMConnection(conn);

// 4. Create an AC4J session over an AC4J connection to the Databus
JEMSession AC4JSess = new  JEMSession(AC4JConn);
// 5. Look up the Active EJB handle using the jem-name defined
//    in the orion-ejb-jar.xml
JEMHandle activeEJBHandle = 
(JEMHandle)context.lookup("JEMPurchaseOrderBean");

// 6. Gather the base Reaction input parameters. These input parameters are
//    required by the receiving method, takeOrder.
Object[] inputParams = new  Object[] { (Object) new  String("user1"), 
                                       (Object) new  Integer("1234-119"),
                                       (Object) new  String("pens"),
                                       (Object) new  Integer("3")   };

// 7. Create the Process Context, Interaction-ID and Activation ID.
//    NOTE: IID = "user1" = requester's name
//          AID = AID = AID_105_user1 = AID_<PO_number>_<cust_name>

// 8. Make the call over the AC4J session providing the parameters.
JEMEmitToken req = AC4JSess.call("user1", "AID_105_user1",
                                 activeEJBHandle, "takeOrder",
                                 null, inputParams, null, 0, 0);

// 9. Commit the changes to the Databus by committing the transaction
conn.commit();

// 10. The client must close the AC4J session and connection because it  
//     does not exist within an AC4J container, which would normally
//     close these.
conn.close();
AC4JConn.close(); 
jemsess.close();
}

The client exists outside of an AC4J server and is requesting a service from an Active EJB through the AC4J data bus. The AC4J data bus is the conduit and controls the asynchronous communication between the client and all reactions. Thus, every client residing outside of an AC4J server must first connect to the AC4J data bus and create a new session for interaction to occur.

After you have retrieved a connection to the AC4J data bus and created an AC4J session within it, you can send asynchronous messages to Active EJBs in the same or other AC4J instances. The AC4J data bus coordinates the asynchronous messages and acts as a transactional manager for all AC4J beans in the transaction. "Connect to the AC4J Data Bus" describes the steps in creating an AC4J-session and completing the client's request.

Connect to the AC4J Data Bus

The following steps detail how to create an AC4J session on the AC4J data bus. These steps are a subset of the steps (those numbered 0 to 4) contained in Example 10-2.

  1. Retrieve an AC4J connection.

    An AC4J connection exists above a JDBC connection. Perform the following:

    1. Retrieve the DataSource defined for the database acting as the AC4J conduit. The DataSource you use should be defined in the data-sources.xml file as a nonemulated data source with a <dblink> defined to the database where the AC4J data bus resides. See "AC4J Data Bus XML Configuration" for more information.

      Context context = new InitialContext();
      DataSource clientDS = (DataSource)
                     context.lookup("java:comp/env/jdbc/jemClientDS");
      
      
    2. Retrieve the JDBC connection off of the DataSource object.

      OracleConnection conn = (OracleConnection)clientDS.getConnection();
      
      
      
    3. Create an AC4J connection off of the JDBC connection object.

      JEMConnection AC4JConn = new JEMConnection(conn);
      
      
  2. Create an AC4J session in a specified data bus. Using the AC4J connection to the database and providing the name of the data bus you are interested in, create a session within the data bus in the indicated Oracle database.

    JEMSession AC4JSess = new  JEMSession(AC4Jconn);
    

Executing an Asynchronous Request

After you have created an AC4J session on the AC4J data bus, the client can send asynchronous messages to Active EJBs. The client must provide the Active EJB handle, the process handle, and all the required input parameters to the base reaction. The following steps explain the details of the call that the client must make to complete the AC4J request.

  1. Process Context: To identify the context where the process exists, you must provide both the interaction identifier and the process activation identifier. The combination of both of these identifiers is the processing context. There are two ways of providing a processing context:

    • Client Provides--The AC4J data bus uses the identifiers provided by the client to uniquely identify the processing context. The client uses the same identifiers to either retrieve the response to the current request or send additional parameters to the process. In the current example, the client supplies the interaction identifier (IID) as a customer's name, and process activation identifier (P-AID) as a union of the purchase order number and the customer's name, as shown:

      String iid = "user1";         // = customer_name 
      String p_aid = "AID_105_user1"; // = AID_<PO_number>_<customer_name>
      JEMEmitToken req = AC4JSess.call(iid, p_aid, ..all other 
      parameters..);
      
      
      
    • Automatic context--The interaction and process activation identifiers are optional and can be omitted or can be null, in which case the system automatically creates them. If a client fails to provide either of these identifiers, then the AC4J data bus creates them to uniquely identify a processing context. However, the client has to retrieve these identifiers and use them later to pull the response from the AC4J data bus.

      JEMEmitToken req = 
               AC4JSess.call (null, null, ...all other parameters...);
      JEMPortHandle portHandle = req.getPortHandle();
      String iid = portHandle.getIid();
      String p_aid = portHandle.getAid();
      
      
  2. Active EJB handle: In a synchronous EJB environment, you would use a remote EJB handle for invocation. In an AC4J asynchronous environment, you must provide a similar handle of class type JEMHandle that identifies an active EJB. OU can get the active EJB handle by looking up the jem-name defined in the orion-ejb-jar.xml file (see "AC4J Active EJB Deployment").

    Context context = new InitialContext();
    JMHandle activeEJBHandle =
              (JEMHandle) context.lookup("JEMPurchaseOrderBean");
    JEMEmitToken req = AC4JSess.call(...., activeEJBHandle, ....);
    
    
  3. Reaction name and input parameters: Client provides the base reaction (method) name and all or part of its input parameters that it wishes to call. In the current example, the client provides all the input parameters to complete the AC4J session call as follows:

    // collect input values for the takeOrder method
    Object[] inputParams = new Object[] { (Object) new String("user1"),
                                          (Object) new Integer("1234-123"),
                                          (Object) new String("pens"),
                                          (Object) new Integer("3")
                                        };
    JEMEmitToken req = AC4JSess.call(..., "takeOrder", null, inputParams,
                                     ...);
    
    
    • If the client provides only some of the parameters to this reaction, then it must supply a set of input parameter types, and the indexes of the input parameters as well. The following example shows how a client can complete a call by furnishing the first two parameters for the takeOrder process:

      
      // input parameter types (java-class) for takeOrder method
      Class[] takeOrderInputClassTypes =
                  new Class[] { String.class, Integer.TYPE,
                                String.class, Integer.TYPE };
      
      // indexes of input parameters you wish to provide for takeOrder method
      int[] indexOfInputParams = new int[] {0, 1};
      
      // input values corresponding to the indexes for takeOrder method
      Object[] inputParams = new Object[] { (Object) new String("user1"),
                                            (Object) new Integer("1234-123")
                                          };
      // remember the interaction and process-activation ids for this call
      JEMEmitToken req =
             AC4JSess.call(iid, p_aid, ..., "takeOrder",
                                  takeOrderInputClassTypes,
                                  indexOfInputParams, inputParams, ...);
      
      
    • When the client provides the remaining two parameters, it must use the same process context (interaction and process activation identifiers) that it used in the first call it made to the process. During the second invocation the steps are:

      // input parameter types (java-class) for takeOrder method
      Class[] takeOrderInputClassTypes =
                  new Class[] { String.class, Integer.TYPE,
                                String.class, Integer.TYPE };
      
      // indexes of input parameters you wish to provide for takeOrder method
      // NOTE: now, client provides the last 2-input parameters
      int[] indexOfInputParams = new int[] {2, 3};
      
      // input values corresponding to the indexes for takeOrder method
      Object[] inputParams = new Object[] { (Object) new String("pens"),
                                            (Object) new Integer("3")
                                          };
      // use the same interaction and process activation ids as those in the 
      // previous call
      JEMEmitToken req =
             AC4JSess.call(iid, p_aid, ..., "takeOrder",
                                  takeOrderInputClassTypes,
                                  indexOfInputParams, inputParams, ...);
      
      
  4. AC4J Session call: Send all asynchronous requests for any Active EJB to the AC4J Session, using the JEMSession::call method.

    When a reaction wants to provide data to an active EJB method (to the base reaction of the process), it executes a JEMSession::call with this information. The JEMSession::call contains the interaction identifier of the EJB, the process activation identifier to identify the process where the method is instantiated, and the JEMHandle of the active EJB. The interaction and process activation identifier are optional and can be omitted or can be null, in which case the system automatically creates them. The data bus identifies the context of the process and routes the data tokens to the intended process. Thus, all EJB calls are invoked asynchronously, through the mediation of the data bus.

  5. Commit Transaction: The client must commit the changes to the AC4J data bus. If the client forgets to commit the transaction, then the request is lost and is not visible to the AC4J data bus. To make the request visible to the AC4J data bus, perform the JDBC commit as follows:

    conn.commit();
    
    
  6. Finally, the client must close the JDBC connection, the AC4J session, and the connection, because the client does not exist within an AC4J container. The AC4J container normally closes the AC4J session and connection objects.

    conn.close(); // client as well an application-code must close
    AC4JConn.close(); // client must close
    jemsess.close(); // client must close
    

Active EJB Processes the Client's Request

Once the client commits the request, the AC4J data bus matches the data tokens provided by the client with those of the requested reaction, and internally schedules the instantiation of the JEMPurchaseOrderBean Active EJB and activation of the takeOrder process. The takeOrder process starts a takeOrder base reaction, which starts a new purchase order. As shown in Figure 7-6, this reaction, takeOrder, processes the client's request by invoking additional services from the other Active EJBs, JEMInventoryBean and JEMCreditBean. This is shown in the following code sample:

Example 10-3 Active EJB Asynchronously Invoking Another Active EJB

public void takeOrder(String clientName, int creditCardNumber,
String itemName, int quantity) throws RemoteException, TestException {

// 0. create a JNDI context
Context context = new InitialContext();

// 1. Retrieve the current AC4J Reaction.
JEMReaction currentAC4JReaction = (JEMReaction) JEMReaction.getReaction();

// 2. Look up the Active EJB handle using the jem-name defined
//    in the orion-ejb-jar.xml
JEMHandle activeInvHandle = (JEMHandle) context.lookup("JEMInventoryBean");

// 3. Gather all input and return parameters for the checkINV Reaction.
//    Define input and return parameter types and the parameter values
Object[] checkINVInputParamValues = 
            new Object[] { (Object)itemName,
                           (Object) new Integer (quantity) };
Class[] checkINVReturnClassType = new Class[] { Boolean.TYPE };

// 4. Request a service from JEMBeancheckINV through Databus
JEMEmitToken inventoryRequest=
               currentAC4JReaction.call(activeInvHandle, "checkINV", null,
                                        checkINVInputParamValues,
                                        checkINVReturnClassType,
                                        null, null, 0,  0);
// 5. Repeat Steps 2-4 above to request a service from another
//    Active EJB, JEMCreditBean. The returned JEMEmitToken is
//    named creditRequest.

// 6. Register a Reaction, procPO, that will be activated when the
//    responses from the above two asynchronous calls to the
//    active-EJBs return
Class[] procPOInputClassTypes = new  Class[] { Boolean.TYPE, String.class };
JEMEmitToken[] requests = new JEMEmitToken[] { inventoryRequest, 
                                               creditRequest };
currentJEMReaction.registerReaction
             ("procPO", procPOInputClassTypes, requests, 1, null, null, 0);
}

The AC4J data bus instantiates the Active EJB, JEMPurchaseOrderBean (corresponding to the JEMHandle provided by the client), in an AC4J server. The takeOrder process starts a takeOrder base reaction. Here are the steps in the completion of this initiation process:

  1. Process Context: The current reaction, takeOrder, is running in an AC4J server. Therefore, it already has a process context and can be used by the application (or Active Bean) code. The application code can retrieve the process context through the demarcation, as follows:

    // retrieve the current-Reaction context--a static method
    JEMReaction currentAC4JReaction = (JEMReaction) JEMReaction.getReaction();
    String iid = currentAC4JReaction.getIid();
    String p_aid = currentAC4JReaction.getAid();
    
    
    • The application may use these identifiers to make additional asynchronous JEMSession::call calls by co-relating the business transaction.

    • Alternatively, the application code can use the currentAC4JReaction to make the additional calls with request-response characteristics. The AC4J data bus then creates a new process context for the next invocation by using the current interaction identifier and a new process activation identifier. The current example uses this approach with the currentAC4JReaction.

  2. AC4J handle: The base reaction, takeOrder, starts the purchase order initiation process by requesting services from two other Active EJBs, JEMInventoryBean and JEMCreditBean. The application code must retrieve the AC4J handles to these Active EJBs by doing the following:

    Context context = new InitialContext();
    // call to JEMInventoryBean
    JEMHandle activeInvHandle = (JEMHandle) context.lookup("JEMInventoryBean");
    JEMEmitToken inventoryRequest= 
                    currentAC4JReaction.call(activeInvHandle, .....);
    
    // call to JEMCreditBean
    JEMHandle activeCreditHandle = (JEMHandle) context.lookup("JEMCreditBean");
    JEMEmitToken creditRequest= 
                    currentAC4JReaction.call(activeCreditHandle, .....);
    
    
  3. Reaction name, return parameter type, and input parameters: The client (now a takeOrder reaction) provides the base reaction (method) name, the java-class type of the return parameter and all or part of its input parameters that it wishes to call. In the current example (which started at "Connect to the AC4J Data Bus"), the client provides all the input parameters needed by the called reactions (checkINV, CheckCRED) as follows:

    // collect input values for the checkINV method
    Object[] checkINVInputParamValues = 
                new Object[] { (Object)itemName,
                               (Object) new Integer (quantity)
                             };
    
    // state the return Class type of checkINV method
    Class[] checkINVReturnClassType = new Class[] { Boolean.TYPE };
    
    // make the call to the checkINV method
    JEMEmitToken inventoryRequest=
                   currentAC4JReaction.call(..., "checkINV", null,
                                            checkINVInputParamValues,
                                            checkINVReturnClassType, ....);
    
    // collect input values for the checkCRED method
    Object[] checkCreditInputParamValues = 
                new Object[] { (Object) clientName,
                               (Object) new Integer (creditCardNumber),
                               (Object) new Float (quantity * 1.4) };
    
    // state the return Class type of checkINV method
    Class[] checkCreditReturnClassType = new Class[] { String.class };
    
    // make the call ro checkCRED method
    JEMEmitToken creditRequest=
                   currentAC4JReaction.call(..., "checkCRED", null,
                                            checkCreditInputParamValues,
                                            checkCreditReturnClassType, ....);
    
    
  4. Register a return reaction: The application code then registers a new reaction, procPO, in the same process context of the currentAC4JReaction. This registration of the reaction requires the reaction name, procPO in this example, the input parameter types of the new procPO reaction, and the JEMEmitTokens retrieved from the call to the currentAC4JReaction. If the new reaction has multiple input parameters and is receiving them from different processes, then the Array of JEMEmitToken must be constructed in proper order. For example, in the following code the first parameter ("procPO") is waiting for the reply from the JEMInventoryBean, and the second one (procPOInputClassTypes) is waiting for the reply from JEMCreditBean.

    Class[] procPOInputClassTypes = new  Class[] { Boolean.TYPE, String.class };
    JEMEmitToken[] requests = new JEMEmitToken[] { inventoryRequest, 
                                                   creditRequest };
    currentJEMReaction.registerReaction
                 ("procPO", procPOInputClassTypes, requests, 1, null, null, 0);
    

Asynchronous Response to the Requesting Active EJB

The takeOrder base reaction is completed only after the AC4J infrastructure commits the transaction that includes the calls to the other two Active EJBs and a registered reaction. The checkINV and checkCRED processes receive the requests from the AC4J data bus as if they were invoked from any other EJB. The JEMInventoryBean and JEMCreditBean Active EJBs are instantiated. The checkINV and checkCRED base reactions are fired when they receive the data tokens from the AC4J data bus, which were initiated from the takeOrder reaction. Both of them receive the request, perform their tasks, and return. The returned values are forwarded by the AC4J data bus to the registered reaction--procPO.

The code sample in Example 10-4 shows the checkINV method. The checkCRED method is similar in its AC4J responsibilities.

Example 10-4 checkINV Processes Request

public boolean checkINV(String itemName, int quantity)
            throws RemoteException, TestException
{

boolean inventoryExists = false;
// The logic in the next step is ommitted
inventoryExists = query its own database for the item and quantity;
return inventoryExists;
}

Asynchronous Response to the Client

Both the checkINV and checkCRED processes return their responses to the procPO reaction through the AC4J data bus. The AC4J data bus makes sure that the return data-tokens have valid takeOrder process context and matches the input parameter types of the procPO reaction. When both parameters arrive, the procPO reaction fires and executes the procPO method of the JEMPurchaseOrderBean Active EJB, which reacts to the information provided by the checkINV and checkCRED processes. It completes the client's request by posting the result to the AC4J data bus. The code sample in Example 10-5 shows the procPO method.

Example 10-5 procPO Reaction Fires

public String procPO(boolean inventoryExists, String creditInfo)
            throws RemoteException, TestException
{
   String poStatus = "Not Shipped";
   if(creditInfo == null)
      return poStatus;
   if (inventoryExists)
   {
      if(creditInfo.equalsIgnoreCase("Credit approved"))
         poStatus = "Shipped";
      else if (creditInfo.equalsIgnoreCase("Credit failed"))
         poStatus = "Credit failed";
   }
   else
      poStatus = "Items unavailable";

   return poStatus;
}

Response from the Client

The client needs to know the response to its purchase order request. As stated earlier, each request (or call) is identified by a process context (interaction ID and activation ID). Using the process context, the client can pull the response from the AC4J data bus.

The received JEMEmitToken from the response can then be parsed by the client. If the client existed inside the OC4J container, the container would deconstruct the JEMEmitToken to the required type. Instead, the client must parse out the response correctly, as shown below:

Example 10-6 Client Processes Return

public static void main(String[] args) throws  ClassNotFoundException, Exception
{

// 0. create a JNDI context
Context  context = new  InitialContext();

// 1. Look up a data source where the databus exists
DataSource clientDS = (DataSource)
                      context.lookup("java:comp/env/jdbc/jemClientDS");

// 2. Get a JDBC-connection to the database where Databus resides
Connection conn = clientDS.getConnection("jemcliuser", "jemclipasswd");

// 3. Create an AC4J connection using the JDBC connection
JEMConnection AC4JConn = new  JEMConnection(conn);

// 4. Create an AC4J session over an AC4J connection to the Databus
JEMSession AC4JSess = new  JEMSession(AC4JConn);

// 5. Look up the Active EJB handle using the jem-name defined
//    in the orion-ejb-jar.xml
JEMHandle activeEJBHandle =
            (JEMHandle) context.lookup("JEMPurchaseOrderBean");

// 6. Retrieve the Response using the Process context with which
//    the initial request was made.
JEMEmitToken  rcvresp = AC4JSess.receiveReactionResponse
          ("user1", "AID_105_user1", activeEJBHandle, "takeOrder", 0);

// 7. The getReactionResponseObjectInstance method parses the returned
//    parameter into an java.lang.Object. 
Object obj = rcvresp.getReactionResponseObjectInstance();
// 8. Print out results
if (obj  instanceof  java.lang.String)
String  ret = (String)  obj;

// 9. The client must commit the transaction 
conn.commit(); 

// 10. The client must close the AC4J session and connection because it  
//     does not exist within an AC4J container, which would normally
//     close these. 
conn.close();
jemsess.close(); 
AC4JConn.close();
}

As seen earlier, the procPO reaction reacts to the information provided by the checkINV and checkCRED processes. It completes the client's request by posting the result to the AC4J data bus. The client must connect to the AC4J data bus to retrieve its response by providing a proper process context. The steps in connecting to the AC4J data bus were described in Example 10-3. After receiving the response, the client can retrieve a java.lang.Object instance that must be processed further.

Retrieving an Asynchronous Response

After creating an AC4J session on the AC4J data bus, the client can retrieve the response by performing the following steps:

  1. Process Context: The client must provide a proper process context that identifies where the request was made, and both the interaction identifier and the process activation identifier. In the example under discussion, the client provides the interaction Identifier (IID) as a customer's name and process activation identifier (P-AID) as a union of purchase order number and the customer's name, as shown:

    String iid = "user1";         // = customer_name 
    String p_aid = "AID_105_user1"; // = AID_<PO_number>_<customer_name>
    JEMEmitToken  rcvresp = AC4JSess.receiveReactionResponse
              (iid, p_aid, ...);
    
    
  2. Active EJB handle: The client must supply the Active EJB handle to which the initial request was made. The Active EJB handle can be obtained by looking up the jem-name defined in the orion-ejb-jar.xml file (see "AC4J Active EJB Deployment").

    Context context = new InitialContext();
    JMHandle activeEJBHandle =
              (JEMHandle) context.lookup("JEMPurchaseOrderBean");
    JEMEmitToken  rcvresp = AC4JSess.receiveReactionResponse
              (..., activeEJBHandle, ...);
    
    
  3. Reaction Name: The client may need to provide the process name to which it initiated the call, which, in this case, is the takeOrder process.

    JEMEmitToken  rcvresp = AC4JSess.receiveReactionResponse
              (..., "takeOrder", ...);
    
  4. Retrieve Object: The JEMEmitToken received from the receiveReactionResponse can be used to retrieve the Object instance, as follows:

    Object obj = rcvresp.getReactionResponseObjectInstance();
    
    
  5. Commit Transaction: The client must commit the changes to the AC4J data bus. If the client forgets to commit the transaction, then the client can pull the response multiple times. However, we do not a recommend this mode of operation. To let the AC4J data bus know that the response was properly retrieved, perform the following:

    conn.commit();
    

AC4J Active EJB Deployment

The active EJB is developed as any other EJB. The changes that enable the EJB to be used in an AC4J interaction are in the OC4J-specific deployment descriptor. These are discussed below:

Deploy the EJB with AC4J element specifications in the OC4J-specific deployment descriptor. The following example defines the takeOrder EJB as an active EJB.

The following is the entire orion-ejb-jar.xml file for the three Active EJBs.

<?xml version="1.0"?>
<!DOCTYPE orion-ejb-jar PUBLIC "-//Evermind//DTD Enterprise JavaBeans 1.1 
runtime//EN" "http://www.orionserver.com/dtds/orion-ejb-jar.dtd">

<orion-ejb-jar deployment-version="1.4.5" deployment-time="e60dffcea9">
<enterprise-beans>

<jem-server-extension 
data-source-location="jdbc/nonEmulatedDS"  
scheduling-threads="1">
<description>AC4J deployment</description>
</jem-server-extension>

<jem-deployment jem-name="JEMPurchaseOrderBean"
             ejb-name="PurchaseOrderBean">
<description>Active Purchase Order bean</description>

<called-by>
<caller  caller-identity="JEMCLIUSER"/>  
</called-by>

<security-identity>
<description>using the caller identity </description>
<use-caller-identity>true</use-caller-identity>
</security-identity>
</jem-deployment>

<jem-deployment jem-name="JEMInventoryBean"
             ejb-name="InventoryBean">
<description>Active Inventory bean</description>

<called-by>
<caller  caller-identity="JEMCLIUSER"/>
</called-by>

<security-identity>
<description>using the caller identity </description>
<use-caller-identity>true</use-caller-identity>
</security-identity>
</jem-deployment>

<jem-deployment jem-name="JEMCreditBean"
             ejb-name="CreditBean">
<description>Active Credit bean</description>

<called-by>
<caller  caller-identity="JEMCLIUSER"/>
</called-by>

<security-identity>
<description>using the caller identity </description>
<use-caller-identity>true</use-caller-identity>
</security-identity>
</jem-deployment>
</enterprise-beans>

Administering AC4J

The remainder of this chapter shows the structure of the AC4J data bus within an Oracle database and refers to administering OC4J to support AC4J.

Administering Oracle Databases to Support AC4J

The createjem script creates a complete JEM repository in the database; the repository is administered by a PL/SQL package called JEMDatabus.


Note:

JEM is an internal name that is equivalent to AC4J.


The complete AC4J packages are shown in the Javadoc, which can be found on the documentation CD accompanying this product or on OTN.

Description of the JEM PL/SQL package

Under the JEMUSER schema the following package is created:

create or replace package  JEMDatabus
procedure  setDatabusProperties(dfbusname  IN VARCHAR2,
                tokttldiff      NUMBER,
                tokttlcalldiff  NUMBER,
                tokttldatdiff  NUMBER,
                rxnttldiff      NUMBER,
                gccycle         NUMBER);

procedure  setTokttldiff(
                dfbusname  IN VARCHAR2,
                tokttldiff      NUMBER);

procedure  setTokttlcalldiff(
                dfbusname  IN VARCHAR2,
                tokttlcalldiff       NUMBER);

procedure  setTokttldatdiff(
                dfbusname  IN VARCHAR2,
                tokttldatdiff      NUMBER);

procedure  setTokclnttldiff(
                 dfbusname  IN VARCHAR2,
                tokclnttldiff      NUMBER);

procedure  setRxnttldiff(
                dfbusname  IN VARCHAR2,
                rxnttldiff       NUMBER);

procedure  setGCcycle(
                dfbusname  IN VARCHAR2,
                gccycle       NUMBER);


procedure  createDatabusTpc(
                 dfbusname                   IN     VARCHAR2  DEFAULT NULL,
                 description                 IN     VARCHAR2  DEFAULT NULL,
                 max_retries                 IN     NUMBER    DEFAULT 1,
                 retry_delay                 IN     NUMBER    DEFAULT 0,
                  retention_time             IN     NUMBER    DEFAULT 0,
                 gccycle                     IN     NUMBER    DEFAULT 10000);

procedure  dropDatabusTpc(dfbusname  IN VARCHAR2  DEFAULT NULL);

procedure  createAppGroupSubscriber(
                 dbusname   IN     VARCHAR2,
                 subname    IN     VARCHAR2 DEFAULT  'JEMSUB');

procedure  dropAppGroupSubscriber(
                 dbusname  IN     VARCHAR2,
                 subname   IN     VARCHAR2 DEFAULT  'JEMSUB');

end  JEMDatabus;

Description of the createDatabusTpc Package Public Method

The following PL/SQL procedure creates a databus:

procedure  createDatabusTpc(
             dfbusname              IN     VARCHAR2  DEFAULT NULL,
             description            IN     VARCHAR2  DEFAULT NULL,
             max_retries            IN     NUMBER    DEFAULT 1,
             retry_delay            IN     NUMBER    DEFAULT 0,
             retention_time         IN     NUMBER    DEFAULT 0,
             gccycle                IN     NUMBER    DEFAULT 10000);

Description of the dropDatabusTpc Package Public Method

The following PL/SQL procedure drops a databus:

procedure  dropDatabusTpc(dfbusname  IN VARCHAR2  DEFAULT NULL);

Description of the JEM Schema Objects

When you create a databus, the following schema objects are created under the JEMUSER schema:

The process also creates unique sequence-numbers and indexes for these tables. It creates multi-consumer queues using DBMS_AQADM package. All the views are created with a public-synonym and are granted to view for public.

Table 10-1 Database Tables
Table Name Description

TABDFB + dfbusname

data bus table

TABPRS + dfbusname

process table

TABRXN + dfbusname

reaction table

TABRTL + dfbusname

match-tuple (reaction template) table

TABTOK + dfbusname

token table (active-data)

TABTRK + dfbusname

tracking table

In Table 10-1, the table name consists of the characters in the Table Name column, with an appended name, represented by dfbusname. This appended name is provided by the user that creates the data bus; the default is the empty string. For example, if the user provides the string _EDB, then the data bus table would be named TABDFB_EDB; if the user makes no specification when creating the data bus, then the data bus table would simply be named TABDFB.

The remainder of this section describes the tables created.

Data Bus Table

Name        = "TABDFB" + dfbusname
          PRIMARY KEY = Instance-ID (or Oracle SID)

Column-Name       Column-Type
--------------------------------------------
 --SID of the database the Databus resides in
 instid          VARCHAR2(50)  PRIMARY KEY,

 --version of the Databus
 version         VARCHAR2(20),

 --Databus Description
 description     VARCHAR2(2000),

 --Latest Databus version number
 scn             NUMBER,

 sysiid          VARCHAR2(50),   --System generated unique ids
 sysaid          VARCHAR2(150),  --System generated unique ids
 glbiid          VARCHAR2(50),   --System generated unique ids
 glbaid          VARCHAR2(150),  --System generated unique ids
 ixnaid          VARCHAR2(150),  --System generated unique ids

 --Default Retry number of a Reaction
 maxrxnretry     NUMBER,

 --State of the Databus (not used now):
--OPEN:
--SUSPENDED:
 state           VARCHAR2(30),

 --creation date of this DATABUS
 creatdate       VARCHAR2(30),

 --The following Data Token types can exist in the Databus:
 --CALL   =created as a result of a Session/Reaction call operation
 --STORE  =created as a result of a Reaction storeData operation
 --RET    =created as a result of a Reaction return result operation
 --EXC    =created as a result of a Reaction throw exception operation
 --SND    =created as a result of a Reaction sendData operation
 --SCHED  =System token, used for triggering a scheduling of a Reaction firing
 --REMATCH=System token, used for triggering the garbage collector to
--begin scanning
 --        for Processes, Reaction and Data Tokens to make unavailable
 --        and then potentially clean.
 --        The garbage collector does the following every 'gccycle' period:
 --           CompactTabTokens:
 --             Mark as 'INVALID' versions of all Tokens that have passed the
 --             TimeToLive (TTL) mark; no more reader/writer Reactions will be
-- able to be matched
 --             using this Data Token.
 --           GarbageCollectTokens:
 --             Delete all 'INVALID' versions of all Data Tokens when all
--reader/writer Reactions
 --             are gone (the reader reference counts and the exclusive
-- modification state of
 --             the Data Token are nulled) and the tokclnttl has passed
 --           GarbageCollectRxns:
 --             Delete all Reactions that are their state is UNMATCHED (no
-- suitable Data Tokens) or
 --             COMPLETED and the rxnttl has passed. Matched Reactions are not
-- deleted, since
 --             the Reaction firing can be scheduled must later of the Reaction
-- matching either
 --             because of resource unavailability or because of user directives
 --           GarbageCollectProcesses:
 --             Delete all Processes that encapsulate no Reactions
 --Default Time a Call Data Token is available for matching in the Databus
 --after it is stored in the Databus
 tokttlcalldiff  NUMBER,

 --Default Time a Return, Exception or Stream Data Token
 --is available for matching will live in the Databus
 --after it is stored in the Databus
 tokttldatdiff   NUMBER,

 --Default Time a Serialized Data Token is available for matching in the Databus
 --after it is stored in the Databus
 tokttldiff      NUMBER,

 --Default Time a Data Token is retained since having being unavailable for
--matching in the Databus
 tokclnttldiff   NUMBER,

 --Default Time a Reaction is available to be matched with available Data Tokens
 --in the Databus
 --after it is created in the Databus
 rxnttldiff      NUMBER,

 --How often the Databus garbage collector runs:
 gccycle         NUMBER,

 epoch           NUMBER,
 epochnext       NUMBER


The TABDBF databus table is initialized with the following values:
         version    =  "1.0"
         sysiid     =  "JEM$SYSIID"
         sysaid     =  "JEM$SYSAID"
         glbiid     =  "JEM$GLBIID"
         glbaid     =  "JEM$GLBAID"
         ixnaid            =  "JEM$IXNAID"
         state             =  "DFBST_INIT"
         dateformat =  "DD-MON-YYYY:HH:MI:SS"

Process Table

Name        = "TabPRS"+dfbusname
          PRIMARY KEY = (iid, aid)

Column-Name       Column-Type
--------------------------------------------
 --
prsseq               NUMBER,

 --interaction-ID; identifies the callee interaction
 iid                  VARCHAR2(50)  NOT NULL,

 --activation-ID; identifies the callee process activation
 aid                  VARCHAR2(150),

 --return IID; identifies the caller interaction
 retiid               VARCHAR2(50),

 --return AID; identifies the caller process activation
 retaid               VARCHAR2(150),

 --JEMHandle; identifies the callee Active EJB
 handle               BLOB,
 handlelen            NUMBER,

 --JEMHandle; identifies the caller Active EJB
 rethandle            BLOB,
 rethandlelen         NUMBER,

 --process-name; identifies the callee Active EJB method name of the base
--Reaction
 prspeid              VARCHAR2(100),

 --
 funpolytup           BLOB,
 funpolytuplen        NUMBER,

 --
 retpolytup           BLOB,
 retpolytuplen        NUMBER,

 excretpolytup        BLOB,
 excretpolytuplen     NUMBER,
 cmpltag              VARCHAR2(250),
 callindx             NUMBER,

 --Not used
 state                VARCHAR2(50),

 flags                NUMBER,

 --start time for the process
 prsstart             VARCHAR2(30),

 --end time for the process
 prsend               VARCHAR2(30),

 --user-ID of starter of the Process activation
 ixnoriginatorusrid   VARCHAR2(50),

 epoch                NUMBER


            - creates a unique index ("Idx1Prs"+dfbusname)
 on ("TabPRS"+dfbusname+prsseq)

Reaction Table

Name        = "TabRXN"+dfbusname
           PRIMARY KEY = (iid, aid, rid, recursid)

Column-Name       Column-Type
--------------------------------
 rxnseq           NUMBER,

 --interaction-ID; identifies the callee interaction
 iid              VARCHAR2(50)  NOT NULL,

 --activation-ID; identifies the callee process activation
 aid              VARCHAR2(150),

 --reaction-ID; identifies the reaction
 rid              VARCHAR2(100),
 recursid         NUMBER,

 --JEMHandle; identifies the callee Active EJB
 handle           BLOB,
 handlelen        NUMBER,

 --process-name; identifies the callee Active EJB method name of the base
--Reaction
 prspeid          VARCHAR2(100),

 --reaction name; identifies the callee Active EJB method name of the fired
--Reaction
 --prspeid is the same as rxnpeid for the base Reaction of a Process
 rxnpeid          VARCHAR2(100),

 --
 grpid            VARCHAR2(100),

 vid              NUMBER,

 --
 funpolytup       BLOB,
 funpolytuplen    NUMBER,

 --number of matching tuples (Data Tokens) that must be matched in order for the
--Reaction to be
 --marked as state=MATCHED
 totmattups       NUMBER,

 mattupsprops     BLOB,
 mattupspropslen  NUMBER,

 --retry count of the Reaction in case of a Reaction rollback; when this count
--reaches the
 --maximum attempts the Reaction is marked state=COMPLETED with status=max
--retries reached
 retrycnt         NUMBER,

 --Reaction states:
 --  UNMATCHED: when the Data Tokens needed for matching
 --             are not available (not arrived in the Databus, not visible yet,
--have conflict in
 --               the interest mode)
 --  MATCHED  : when the Data Tokens  needed for matching are available
 --  COMPLETED: when the Reaction commits or rollbacks with exception status
--message
 state            VARCHAR2(50),

 --Reaction statuses:
 --   PRSUNMATCHED:
 --   RXNDISCARDED:
 --   RXNMAXRETRY :
-- COMMITED:
 status           VARCHAR2(50),

 --Type of the Reaction:
 --  CALL : if it is a base Reaction (implicitly created by the Databus)
 --  MATCH: if it is not a base Reaction (explicitly created by the application)
 type             VARCHAR2(50),

 flags            NUMBER,

 --Reaction priority: Reactions registered in a Process when matched are firing
--ordered by the
 --time of registration if they have the same priority.
 --The firing ordering is:
 --    order by ReactionPriority descending, ReactionRegistrationTime ascending
 rxnpri           NUMBER,

 --time-to-live for the reaction
 rxnttl           VARCHAR2(30),

 --description of this reaction
 descr            VARCHAR2(2000),

 --date of the reaction registration as Julian date
 rxndate          NUMBER,

 --date of the reaction registration
 rxnstart         VARCHAR2(30),

 --date of the reaction commit
 rxnend           VARCHAR2(30),

 --user-ID of registered this reaction
 schemausrid      VARCHAR2(50),

 schemamsgid      VARCHAR2(50),

 auxctx           BLOB,
 auxctxlen        NUMBER,
 epoch            NUMBER,

 --Time a Call Data Token is available for matching in the Databus
 --after it is stored in the Databus
 tokttlcalldiff  NUMBER,

 --Time a Return, Exception or Stream Data Token
 --is available for matching will live in the Databus
 --after it is stored in the Databus
 tokttldatdiff   NUMBER,

 --Time a Serialized Data Token is available for matching in the Databus
 --after it is stored in the Databus
 tokttldiff      NUMBER,

 --Time a Data Token is retained since having being unavailable for matching
 --in the Databus
 tokclnttldiff   NUMBER,

 --Time a Reaction is available to be matched with available Data Tokens
 --in the Databus
 --after it is created in the Databus
 rxnttldiff      NUMBER


            - creates a unique index ("Idx1RXN"+dfbusname)
 on ("TabRXN"+dfbusname+"  "+(iid, aid, rid, recursid, prspeid, rxnpeid, grpid,
state))

            - create a unique index ("Idx2RXN"+dfbusname)
 'on ("TabRXN"+dfbusname+"  "+rxnseq)

Reaction Template Table

Name       = "TabRTL"+dfbusname

Column-Name       Column-Type
--------------------------------------------
 mattupseq     NUMBER,

 --every Reaction template needed for matching a Data Token has an index,
--starting from 0
 --This is used for a composite Reaction matching
 matindx       VARCHAR2(50)   NOT NULL,

 --1. First level of matching:
 -- The following 3 conditions need to be valid for a template to match with a
--Data Token
 --

 --1.1: Interaction-ID that needs to match with a Data Token's Interaction-ID
 tokiid        VARCHAR2(50),

 --1.2: Activation-ID that needs to match with a Data Token's Activation-ID
 tokaid        VARCHAR2(150),

 --1.3: tag name that needs to match with a Data Token's tag name
 tag           VARCHAR2(250),

 --
 vid           NUMBER,
 vidtype       VARCHAR2(50),

 --2. Second level of matching:
 --The filter conditions specified here need to be true for the propereties of
--the Data Token matched in the first level
 polycnd       CLOB,
 polycndlen    NUMBER,

 --Interaction-ID of the Reaction this template belongs to
 iid           VARCHAR2(50)  NOT NULL,

 --Activation-ID of the Reaction this template belongs to
 aid           VARCHAR2(150),

 --Reaction-ID of the Reaction this template belongs to
 rid           VARCHAR2(100),
 recursid      NUMBER,

 --java-class type of the object value that is needed for matching
 objclassname  VARCHAR2(1000),

 --Reaction template states:
 --  UNMATCHED: when the Data Token needed for matching
 --             is not available (not arrived in the Databus, not visible yet,
--have conflict in the interest mode)
 --  MATCHED  : when the Data Token needed for matching is available
 state         VARCHAR2(50),

 type          VARCHAR2(50),

 flags         NUMBER,

 --Same as Reaction priority
 rxnpri        NUMBER,

 timeout       NUMBER,

 --Same as Reaction rxnttl
 rxnttl        VARCHAR2(30),

 --Same as Reaction rxndate
 rxndate       NUMBER,

 --points to the Data Token when this template is MATCHED; otherwise null
 tokseq        NUMBER,

 --Scope Interaction-ID; used to minimize the matching process phase
 scpiid        VARCHAR2(1000),

 --Scope Activation-ID; used to minimize the matching process phase
 scpaid        VARCHAR2(1000),

 epoch         NUMBER


            - creates an index ("Idx1RTL"+dfbusname)
 on ("TabRTL"+dfbusname+"  "+(iid, aid, rid, recursid, state))
            - creates an index ("Idx2RTL"+dfbusname)
 on ("TabRTL"+dfbusname+"  "+(tokiid, tokaid, tag))
            - create a unique index ("Idx3RTL"+dfbusname)
 'on ("TabRTL"+dfbusname+"  "+mattupseq)

Token (Active Data) Table

         Name        = "TabTOK"+dfbusname
         PRIMARY KEY = sequence-number

Column-Name       Column-Type
--------------------------------------------
 --identifies uniquely this Data Token. A matched Reaction template
 --points to this id
 tokseq        NUMBER   PRIMARY KEY,

 --Data Tokens are chained:
 --seq-number of the previous version of the Data Token
 prevtokseq    NUMBER,

 --seq-number of the next version of the Data Token
 nexttokseq    NUMBER,

 aliastokseq   NUMBER,

 --Interaction-ID of this data-token
 iid           VARCHAR2(50)  NOT NULL,

 --Activation-ID of this data-token
 aid           VARCHAR2(150),

 --
 tag           VARCHAR2(250),
 classtag      VARCHAR2(10),

 --
 vid           NUMBER,
 prevvid       NUMBER,
 nextvid       NUMBER,

 --
 polycnd       CLOB,
 polycndlen    NUMBER,

 --
 objinst       BLOB,
 objinstlen    NUMBER,
 textinst      CLOB,
 textinstlen   NUMBER,

                undoentry     BLOB,
 undoentrylen  NUMBER,

 --used to describe the number of Reactions having matched a query interest
 --on this Data Token
 readers       NUMBER,

 consumer      VARCHAR2(100),

 --Data Token states:
 --  UNMATCHED: when the Data Token is not matched by a Reaction template or
--matched in query interest mode
 --  MATCHEDX  : when the Data Token is matched by a Reaction template in
--exclusive modification interest mode
 state         VARCHAR2(50),

 --Data Token statuses:
 --  VALID  : Tok is available; so readers can see it and a writer can reserve 
it
 --  INVALID: Tok is unavailable because its time-to-live has expired; nobody 
can
--access it
 status        VARCHAR2(50),


 --     CALL   :
 --     MATCH  :
 --     STORE  :
 --     RET    :
 --     EXC    :
 --     SND    :
 --     SCHED  :
 --     REMATCH:
 --     QUIT   :
 --
 op            VARCHAR2(50),

 reason        VARCHAR2(50),

 type          VARCHAR2(50),

 flags         NUMBER,

 --Time Data Token is available for matching in the Databus
 --after it is stored in the Databus
 tokttl        VARCHAR2(30),

 --Time a Data Token is retained since having being unavailable for matching
 --in the Databus
 tokclnttl     VARCHAR2(30),

 --date of the Data Token creation
 toktime       VARCHAR2(50),

 --user-ID of the who created this Data Token
 schemausrid   VARCHAR2(50),

 schemamsgid   VARCHAR2(50),

 auxctx        BLOB,
 auxctxlen     NUMBER,

 --description of this Data Token
 descr         VARCHAR2(2000),

 epoch         NUMBER


            - creates an unique index ("Idx1TOK"+dfbusname)
 on ("TabTOK"+dfbusname+"  "+(iid, aid, tag, vid))

Tracking Table

Name        = "TabTRK"+dfbusname
           PRIMARY KEY = sequence-number

Column-Name       Column-Type
--------------------------------------------
 trkseq        NUMBER  PRIMARY KEY,

 --token seq-number
 tokseq        NUMBER,

 --instance-ID = Oracle_SID
 instid        VARCHAR2(100),

 --Interaction-ID; identifies the caller interaction
 iid           VARCHAR2(50),

 --Activation-ID; identifies the caller process activation
 aid           VARCHAR2(150),

 --JEMHandle; identifies the caller Active EJB
 handle        VARCHAR2(2000),

 --reaction ID; identifies the caller Reaction
 rid           VARCHAR2(100),
 recursid      NUMBER,

 --Data Token push operation; see above
 op            VARCHAR2(50),

 --Data Token push reason; see above
 reason        VARCHAR2(50),

 --Interaction-ID; identifies the callee interaction
 toiid         VARCHAR2(50),

 --Activation-ID; identifies the callee process activation
 toaid         VARCHAR2(150),

 --JEMHandle; identifies the callee Active EJB
 tohandle      VARCHAR2(100),

 --process-name; identifies the callee Active EJB method name of the base
--Reaction
 toprspeid     VARCHAR2(100),

 --reaction name; identifies the callee Active EJB method name of the fired
--Reaction
 --prspeid is the same as rxnpeid for the base Reaction of a Process
 torxnpeid     VARCHAR2(100),

 --description of this tracking info
 description   VARCHAR2(2000),

 --date of the Data Token push
 trkdate       VARCHAR2(30),

 --user-ID of the who pushed the Data Token
 schemausrid   VARCHAR2(50),

 schemamsgid   VARCHAR2(50),

 --  Direction of the push:
 --    SND: at the sending side (caller with a call operation, callee with a
--return operation)
 --    RCV: at the receiving side (callee with a call operation, caller with a
--return operation)
 direction     VARCHAR2(50),

 epoch         NUMBER
Table 10-2 Advanced Queueing Topics
AQ Topic Name Description

JEMUSER.QT + dfbusname

queue table

JEMUSER.MQ + dfbusname

match queue

JEMUSER.SQ + dfbusname

scheduling queue

JEMUSER.FQ + dfbusname

foreign queue

JEMUSER.AQ$_QT + dfbusname + E

exception queue

In Table 10-2, the queue name consists of the characters in the AQ Topic Name column, plus an appended string, represented by dfbusname. This appended name is provided by the user that creates the data bus; the default is the empty string. For example, if the user provides the string _EDB, then the scheduling queue would be named JEMUSER.SQ_EDB; if the user makes no specification when creating the data bus, then the scheduling queue would simply be named JEMUSER.SQ. In the case of the exception queue, the character E is appended at the end.

The remainder of this section describes the AQ schema objects created.

Create AQ Queue table, topics, and default subscriber to all topics using AQ PL/SQL Packages. For every J2EE application deployed to OC4J, the JEM runtime system will add a subscriber to all topics with the J2EE application name deployed used as the subscriber name.

In the following descriptions, dfbusname is the string provided by the user that creates the data bus; the default is the empty string.

Queue Table

DBMS_AQADM.CREATE_QUEUE_TABLE(
	Queue_table            => quetablename,
	Multiple_consumers     => TRUE,
		Queue_payload_type     => 'SYS.AQ$_JMS_BYTES_MESSAGE',
	compatible             => '8.1.5');

Match Queue

DBMS_AQADM.CREATE_QUEUE(
	Queue_name          => matchquename,
	Queue_table         => quetablename,
	max_retries         => max_retries,
	retry_delay         => retry_delay,
	retention_time      => retention_time);

Create and add the subscriber to MATCH-Queue
subscriber :=
	sys.aq$_agent('JEMSUB' || dfbusname, null, null);

DBMS_AQADM.ADD_SUBSCRIBER(
	queue_name           => matchquename,
	subscriber           => subscriber);

Scheduling Queue

DBMS_AQADM.CREATE_QUEUE(
		Queue_name          => schedquename,
	Queue_table         => quetablename,
	max_retries         => max_retries,
	retry_delay         => retry_delay,
	retention_time      => retention_time);

Create and add the subscriber to SCHEDULING-Queue
	subscriber :=
	sys.aq$_agent('JEMSUB' || dfbusname, null, null);

DBMS_AQADM.ADD_SUBSCRIBER(
	queue_name           => schedquename,
	subscriber           => subscriber);

Foreign Queue

DBMS_AQADM.CREATE_QUEUE(
	Queue_name          => foreignquename,
	Queue_table         => quetablename,
	max_retries         => max_retries,
	retry_delay         => retry_delay,
	retention_time      => retention_time);

Create and add the subscriber to FOREIGN-Queue
	subscriber :=
	sys.aq$_agent('JEMSUB' || dfbusname, null, null);

DBMS_AQADM.ADD_SUBSCRIBER(
	queue_name           => foreignquename,
	subscriber           => subscriber);
Table 10-3 Database Views
View Name Description

DFB + dfbusname

data bus view

PRS + dfbusname

process view

RXN + dfbusname

reaction view

RTL + dfbusname

reaction template view

TOK + dfbusname

token view (active-data)

TRK + dfbusname

tracking view

In Table 10-3, the view name consists of the characters in the View Name column, plus an appended string, represented by dfbusname. This appended name is provided by the user that creates the data bus; the default is the empty string. For example, if the user provides the string _EDB, then the data bus view would be named DFB_EDB; if the user makes no specification when creating the data bus, then the data bus table would simply be named DFB.

Data Bus View

Name       =  ("DFB"+dfbusname) [ from ("TabDFB"+dfbusname) ]

               Column-Name
               ------------
                instid,                  (Instance-ID or Oracle-SID)
                version,
                maxrxnretry,
                state,
                creatdate,
                tokttldiff,
                tokttlcalldiff,
                tokttldatdiff,
                tokclnttldiff,
                rxnttldiff,
                gccycle

Process View

Name           =  "PRS"+dfbusname

               Column-Name
               ------------
                iid            ,   (Interaction-ID)
                aid            ,   (Activation-ID)
                retiid         ,   (return IID)
                retaid         ,   (return AID)
                rethandlelen   ,
                prspeid        ,   (process name=method name)
                cmpltag        ,
                state          ,
                flags          ,
                prsstart       ,
                prsend

Reaction View

Name="RXN"+dfbusname [ from ("TabRXN"+dfbusname) ]

               Column-Name
               ------------
                iid            ,   (Interaction-ID)
                aid            ,   (Activation-ID)
                rid            ,   (Reaction-ID)
                recursid       ,
                prspeid        ,   (process name)
                rxnpeid        ,   (reaction name)
                grpid          ,
                totmattups     ,
                retrycnt       ,
                state          ,
                status         ,
                type           ,
                flags          ,
                rxnpri         ,
                rxnttl         ,
                descr          ,
                rxndate        ,
                rxnstart       ,
                rxnend

Reaction Template View

Name       =  "RTL"+dfbusname [ from ("TabRTL"+dfbusname) ]

               Column-Name
               ------------
                mattupseq      ,
                matindx        ,
                tokiid         ,
                tokaid         ,
                tag            ,
                vid            ,
                vidtype        ,
                iid            ,   (Interaction-ID)
                aid            ,   (Activation-ID)
                rid            ,   (Reaction-ID)
                recursid       ,
                polycnd        ,
                objclassname   ,   (java-class name of the obj for reaction)
                state          ,
                type           ,
                flags          ,
                rxnpri         ,   (priority of the reaction)
                timeout        ,   (timeout for the reaction)
                tokseq         ,
                scpiid         ,
                scpaid

Token (Active Data) View

Name              =  "TOK"+dfbusname

               Column-Name
               -------------
                tokseq         ,
                prevtokseq     ,
                nexttokseq     ,
                aliastokseq    ,
                readers        ,
                consumer       ,
                status         ,
                iid            ,   (Interaction-ID)
                aid            ,   (Activation-ID)
                tag            ,
                vid            ,
                prevvid        ,
                nextvid        ,
                polycnd        ,
                textinst       ,
                textinstlen    ,
                state          ,
                op             ,
                reason         ,
                type           ,
                flags          ,
                tokttl         ,
                tokclnttl      ,
                toktime

Tracking View

Name =  "TRK"+dfbusname [ from "TabTRK"+dfbusname and from "TabTOK'"+dfbusname ]
                         Condition   =  trk.tokseq = tok.tokseq  AND
                                        trk.schemausrid = (select UPPER(user) 
from dual)))

               Column-Name
               ------------
                tok.tokseq        ,   (seq-number if the token)
                tok.prevtokseq    ,   (prev seq-number for the token)
                tok.nexttokseq    ,   (next seq-number for the token)
                tok.aliastokseq   ,
                tok.readers       ,
                tok.consumer      ,
                tok.status        ,
                tok.iid           ,   (Interaction-ID of the token)
                tok.aid           ,   (Activation-ID of the token)
                tok.tag           ,
                tok.vid           ,
                tok.prevvid       ,
                tok.nextvid       ,
                tok.polycnd       ,
                tok.state         ,
                tok.type          ,
                tok.flags         ,
                tok.tokttl        ,   (time-to-live for the token)
                tok.tokclnttl     ,
                tok.toktime       ,
                trk.instid        ,   (instance-ID or Oracle-SID)
                trk.iid              ,   (Interaction-ID for tracking)
                trk.aid              ,   (Activation-ID for tracking)
                trk.rid           ,   (Reaction-ID for tracking)
                trk.recursid      ,
                trk.op            ,
                trk.reason        ,
                trk.toiid         ,
                trk.toaid         ,
                trk.tohandle      ,
                trk.toprspeid     ,
                trk.torxnpeid     ,
                trk.description   ,
                trk.direction     ,
                trk.trkdate


Go to previous page Go to next page
Oracle
Copyright © 2002 Oracle Corporation.

All Rights Reserved.
Go To Core Documentation
Core
Go To Platform Documentation
Platform
Go To Table Of Contents
Contents
Go To Index
Index