Download Autonomous and Distributed Transactions in Oracle 8i/9i Nandeep

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Database wikipedia , lookup

Global serializability wikipedia , lookup

SQL wikipedia , lookup

Clusterpoint wikipedia , lookup

PL/SQL wikipedia , lookup

Commitment ordering wikipedia , lookup

Versant Object Database wikipedia , lookup

Expense and cost recovery system (ECRS) wikipedia , lookup

Concurrency control wikipedia , lookup

Serializability wikipedia , lookup

Transcript
Autonomous and Distributed
Transactions in Oracle 8i/9i
Nandeep Nagarkar
1. Introduction
This article presents a basic introduction to transaction processing in PL/SQL and
primarily focuses on the Autonomous transaction processing feature of PL/SQL
and the changes that have occurred from Oracle 8i (8.1.7) to 9i (9.2.0.1.0).
In the following sections, I will define transaction and describe the use of
distributed transactions and autonomous transactions, followed by a special
case, the combined use of distributed and autonomous transactions, and the
changes introduced in Oracle9i.
2. Transaction Defined
The simple definition of a transaction in a DBMS is to ADD, DELETE or
UPDATE rows in the database.
The ANSI/ISO SQL standard definition of a transaction is a logical unit of work
that comprises all the executable SQL statements executed by a single user that
ends when an explicit COMMIT or ROLLBACK statement is issued by the user.
Transactions can be of 3 types:
1)
Non-Distributed transactions, which manipulate or query only a single
database (the local database where the user is logged in).
2)
Distributed transactions, which manipulate or query more than one node in a
distributed database.
3)
Remote transactions, which manipulate or query only a remotely located
database.
3. Distributed Transaction Defined
Unlike the non-distributed transactions that involve SQL statements against a
single node of a database (the local node where the user is logged in), the
Distributed transaction involves all DML (Data Manipulation Language)
operations on two or more nodes of a distributed database.
Example 1
/* The distributed transaction starts from here */
INSERT INTO local. account_header (account_id, customer_id, account_type,
acct_start_date)
VALUES (1010,'C123','SB', SYSDATE);
INSERT [email protected]
(account_id, customer_id, account_type, acct_start_date)
VALUES (1010,'C123','SB', SYSDATE);
COMMIT;
/* The distributed transaction ends after the COMMIT that follows the INSERT
statement */
The transaction in this case consists of two DML statements -- one DML in the
local database and the next in the remote database identified by us.remotedb.com
4. Autonomous Transaction Defined
In PL/SQL, transaction processing takes place serially. That is, a new transaction
can begin only when the earlier transaction ends, in which case the user issues
an explicit Commit or Rollback statement.
Quite often, however, your application may require you to commit or rollback
changes without affecting the main transaction in the session.
For example, consider a simple banking transaction in which a customer
transfers funds from one account to another account. A single commit or rollback
should end this transaction. (Obviously! The customer may not find it pleasant to
see one of his accounts debited but the other show no credits in the case of
some unexpected failure.) However, your application requires recording each
activity (on each of the accounts) in a transaction history table located in a
remote database.
Thus, your main transaction would debit the customer's account (A) with the
specified transaction amount, record the transaction activity (an autonomous
transaction whose commit should not affect the main transaction), and then credit
account (B) with the new amount, record the update and then commit the main
transaction.
From PL/SQL 8.1 onwards it is possible to achieve the goal of having to rollback
some change in the main transaction while committing the log entry (the
transaction history) by the issuing the PL/SQL compiler
directive AUTONOMOUS_TRANSACTION.
In order to use autonomous transactions, you simply have to include the
following statement in your declaration section:
PRAGMA AUTONOMOUS_TRANSACTION
Example 2
CREATE OR REPLACE PROCEDURE log_acct_txn (
p_acct_id
IN
NUMBER,
p_txn_type
IN
VARCHAR2,
p_txn_amount IN NUMBER)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
acct_id
account_header.account_id%type;
txn_type
VARCHAR2(4);
txn_amount NUMBER;
BEGIN
INSERT INTO [email protected] ( account_id,
txn_type,amount, txn_date)
VALUES (acct_id,cr_type,txn_amount,SYSDATE);
COMMIT;
END;
The block in this example now becomes an independent transaction, and the
COMMIT issued in this block will not affect the SQL statements in the main
transaction.
When you call this procedure log_acct_txn in a block, it acts as an independent
block of code and suspends the Main transaction. The main transaction will
resume once the procedure completes execution.
5. Rules of Autonomous Transaction
Typically, a program block can be made an autonomous transaction as shown in
the preceding examples. However, some rules to follow in using autonomous
transactions are:
1. Nested blocks cannot be declared as autonomous transactions.
Example 3
DECLARE
acct_id
NUMBER;
BEGIN
declare
pragma autonomous_transaction;
begin
Insert [email protected]
(account_id, customer_id, account_type, acct_start_date)
values (1010,'C123','SB', SYSDATE);
commit;
end;
END;
results in the following error:
PLS-00710: PRAGMA AUTONOMOUS_TRANSACTION cannot be declared
here.
2.
An autonomous transaction must have a COMMIT or a ROLLBACK
statement before it completes execution. Otherwise the following error is
generated:
ORA-06519: active autonomous transaction detected and rolled back.
3.
As the autonomous transaction is an independent transaction, you cannot
rollback to a savepoint defined in the main transaction. If you attempt to do
so, you will receive the error:
ORA-01086: savepoint ' specified savepoint' never established.
4.
Again, calling one autonomous transaction in the main transaction in your
session implies the session is concurrently running two sessions and so on.
The maximum number of such concurrent transactions in your session is
determined by the Oracle initialization parameter file (init.ora) parameter
TRANSACTIONS. If you use a large number of autonomous transaction
programs in your application that exceed the value set for the parameter, you
will run into the following error:
ORA-01574: maximum number of concurrent transactions exceeded.
5.
You cannot declare a package as an autonomous transaction to make all
procedures/functions as autonomous transactions. If you do so, you will get
this error:
PLS-00710: PRAGMA AUTONOMOUS_TRANSACTION cannot be declared
here.
6.
Finally, if your autonomous transaction tries to access a resource held by the
main transaction that is suspended, it will result in a deadlock situation giving
the error:
ORA-00054: resource busy and acquire with NOWAIT specified.
6. Using Autonomous Transactions within a Distributed
Transaction
Consider a scenario where you have a distributed transaction in which you
require to commit or rollback a change in a remote table followed by an
insert/update/query on your local database, or vice versa. In such a case, you
would most likely take advantage of the autonomous feature described in the
preceding section.
Example 4
/* A simple example that I have tested on Oracle8.1.7 and Oracle 9.2.0.1.0) */
/* Debit the customer's account only if the minimum balance limit is met
else rollback. However, record the activity.
*/
DECLARE
var1 NUMBER;
var2 NUMBER;
BEGIN
--SQL statements ….
---
/* The procedure debits the amount from the account but does not
commit/rollback any changes */
debit_acct (acct_id, txn_amount) ;
/* Calling the autonomous transaction that is shown in the preceding example to
log the activity in a remote table txn_history */
log_acct_txn ( acct_id , txn_type , txn_amount) ;
/* Once again query a local table */
IF min_bal_maintained(acct_id) THEN
COMMIT;
ELSE
ROLLBACK;
END IF;
-more statements
-END;
When this example is executed in Oracle8.1.6/8.1.7, it will result in the error:
ORA-00164: autonomous transaction disallowed within distributed
transaction
This is because Oracle8i does not support autonomous transactions within a
distributed query.
In Oracle 8.1.7, one of the ways to work around the limitation is to use the control
statement SET TRANSACTION READY ONLY in your programs. However, the
use of the SET TRANSACTION READ ONLY control statement means only a
SELECT statement can follow the autonomous transaction and no other DML is
permitted. Using SET TRANSACTION READ ONLY just after the BEGIN
statement will not give any errors as the transaction is made READ ONLY and,
as a result, no changes are made to the remote database.
7. New in Oracle9i (9.2.0)
As of version 9.2.0 of Oracle9i, this limitation has been removed to a limited
extent. Example 4 in the preceding section, when run in Oracle 9i (9.2.0), will not
give you any errors.
ORA-00164 is now redefined to:
ORA-00164 distributed autonomous transaction disallowed within
migratable distributed transaction
In oracle 9i (9.2.0), this error is now defined in context to the use of Oracle XA
library with Transaction Monitors (TM). Normally, Oracle acts as its own TM and
manages its own commit and recovery. However, it also provides for using a
standards-based TM.
Essentially, Oracle 9.2.0 has changed the way it treats the boundaries of a
transaction between its own role as a TM and that of an external TM.
The concepts of migratable transactions and transaction monitors will be
discussed in detail in future articles.