Oracle7 Server Distributed Systems Volume II: Replicated Data
Determining the Cause of an Error
When Oracle pushes a deferred transaction from a snapshot or master site to another master site, it uses two-phase commit to ensure that the transaction is not removed from the local queue until it has been successfully propagated to the remote site. A transaction can be successfully propagated without being successfully applied. An error in applying a deferred transaction may be the result of a database problem, such as a lack of available space in a table that you are attempting to update, or may be the result of an unresolvable update conflict. If an error occurs, Oracle performs the following actions at the destination site:
- rolls back the transaction
- logs the error in the DefError view
- adds the transaction to the local deferred transaction views (since it is no longer queued for this location at the originating site)
Deferred transactions consist of a series of deferred remote procedure calls that must be applied in a given order to maintain transaction consistency. The DefError view provides the ID of the transaction that could not be applied. You can use this ID to locate the queued calls associated with this transaction. These calls are stored in the DefCall view. You can use the procedures in the DBMS_DEFER_QUERY package to determine the arguments to the procedures listed in the DefCall view.
After you successfully resolve the error at the destination site, it is removed from the DefError view, as well as the DefCall and DefTran views at the destination site. Because the transaction queued for this site was removed from the originating queue when the transaction was originally pushed, resolving the transaction at the destination site has no effect on the queue at the originating site.
Determining the Type of an Argument
The DefCall view provides you with the name of each remote procedure call associated with a particular deferred transaction, and the number of arguments to the procedure. Before you can get the value of an argument to a deferred remote procedure call, you must know the type of the argument. Use the GET_ARG_TYPE function in the DBMS_DEFER_QUERY package to determine the type of an argument, as shown in the following example:
type_no := DBMS_DEFER_QUERY.GET_ARG_TYPE(
call_no => 234,
deferred_tran_db => 'acct_hq.hq.com',
arg_no => 3,
deferred_tran_id => '1.7.356');
In this example, the GET_ARG_TYPE function returns the datatype of the third argument to the deferred remote procedure call with ID number 234 that originated from the ACCT_HQ database.
Additional Information: The parameters for the GET_ARG_TYPE function are described in Table 12 - 9, the exceptions are listed in Table 12 - 10, and the possible return values are described in Table 12 - 11.
Determining the Value of an Argument
Once you know the type of an argument to a deferred remote procedure call, you can next determine the value of this argument by using the appropriate function in the DBMS_DEFER_QUERY package. For example, if you wanted to get the value of an argument of type VARCHAR2, you would use the GET_VARCHAR2_ARG function, as shown in the following example:
val := DBMS_DEFER_QUERY.GET_VARCHAR2_ARG(
callno => 234,
deferred_tran_db => 'acct_hq.hq.com',
arg_no => 3)
Whereas the call to GET_ARG_TYPE in the previous example returned only the datatype of the third argument to the procedure with ID number 234, the call to the GET_VARCHAR2_ARG function returns the actual value passed for this argument.
The type of the argument value that you want to retrieve determines the name of the function that you need to call. The supported datatypes are: NUMBER, VARCHAR2, CHAR, DATE, RAW, and ROWID. The datatype of the return value must match the datatype of the function name.
Additional Information: The parameters for all of the GET_datatype_ARG functions are described in Table 12 - 12, and the exceptions are listed in Table 12 - 13.