Database Journal
MS SQL Oracle DB2 Access MySQL PostgreSQL Sybase PHP SQL Etc SQL Scripts & Samples Links Database Forum

» Database Journal Home
» Database Articles
» Database Tutorials
MS SQL
Oracle
DB2
MS Access
MySQL
» RESOURCES
Database Tools
SQL Scripts & Samples
Links
» Database Forum
» Sitemap
Free Newsletters:
DatabaseDaily  
News Via RSS Feed


follow us on Twitter
Database Journal |DBA Support |SQLCourse |SQLCourse2
 

Featured Database Articles

Oracle

Posted Mar 10, 2004

Use Oracle's DBMS_APPLICATION_INFO to Prevent Routines from Running Simultaneously

By Amar Kumar Padhi

On occasion, it may be necessary to implement business logic where, when one routine or business process is being run by a user, certain other routine(s) should not be allowed to run and vice versa. This requirement may be a functional or a technical need.

You may be able to relate to the following scenarios:

  1. A critical accounting process is triggered by a user. It is necessary to avoid multiple runs of the same process at any given time. Therefore, if one user has triggered the process, others should be prevented from doing so.
  2. Heavy data loading processes or data interfacing may require that two routines do not run simultaneously. When a heavy upload is triggered, simultaneous uploads from other sources should be prevented until resources are available for use.
  3. Several heavy-duty batch processes exist in the system and proper resource sharing should be done. Running multiple batch processes may slow down the system and eventually result in resource contentions. Preventing such identified processes from running simultaneously is necessary.
  4. Two or more processes carry out DML activities on common objects, which may result in locking issues. This could give rise to errors like 0RA-00054 (resource busy) or ORA-00060(deadlock detected).

One solution would be to request that users avoid running identified processes simultaneously; however, this is a manual control that can be easily overlooked, requiring the DBA to kill the bad sessions to avoid database congestion.

Using code, developers normally use flags or locks set in some table that is referred to by all sessions. This will not work if the session is killed or closed abnormally. Explicit coding needs to be done in such cases to make the system foolproof; this could again amount to an overhead.

The Oracle provided package, DBMS_APPLICATION_INFO, could be used to satisfy this requirement, thus preventing the abnormal situations mentioned above from arising.

Register the routine that is being run by calling DBMS_APPLICATION_INFO.SET_MODULE. This tags the routine name in V$SESSION dynamic view. Check for this information at the beginning of the concerned routines. Once a routine is complete, unregister it. Note when a session is abnormally closed or killed, V$SESSION is updated accordingly. There is no need of commit or rollback or explicit updates.

Three columns, MODULE, ACTION and CLIENT_INFO can be set in V$SESSION using DBMS_APPLICATION_INFO which could later be referred to, to identify processes already running in the system. The following example sets these three columns.

begin
  dbms_application_info.set_module(module_name => 'File Upload Process', 
                                   action_name => 'Uploading file');
  dbms_application_info.set_client_info('WDA001');
end;

On running the above code, the three columns are set with the value provided, and can be viewed from V$SESSION.

SQL> select module, action, client_info
  2  from v$session
  3  where sid = (select sid from v$mystat where rownum = 1);

MODULE               ACTION               CLIENT_INFO
-------------------- -------------------- --------------------
File Upload Process  Uploading file       WDA001

If direct access to the dictionary is not available, the set data can be viewed using the same package.

declare
  l_client_info  varchar2(64);
  l_module      varchar2(48);
  l_action        varchar2(32);
begin
  dbms_application_info.read_module(l_module, l_action);
  dbms_application_info.read_client_info(l_client_info);

  dbms_output.put_line(l_module||'/'||l_action||'/'||l_client_info);
end;

Output:
File Upload Process/Uploading file/WDA001

The data returned in the above case is only for the current session. For our situation it is required that access be given to V$SESSION to view all sessions data. Select privilege can be granted to the public so that all logins have access to it.

SQL> grant select on v_$session to public;

Grant succeeded.

Let's look at an example. This is a very specific example but generic code could be written along similar lines. AM_DEP1 and AM_DEP2 are inter-dependent procedures and should not run simultaneously. The following function checks to see if a particular procedure session is active and returns the status accordingly.

create or replace function chk_dep_run (pi_proc in varchar2)
return boolean is
  l_cnt  pls_integer; 
begin
  select 1 
  into   l_cnt 
  from   v$session 
  where  module = pi_proc
  and    rownum = 1;     

  return(false);
exception 
  when no_data_found then 
    return(true);
end; 

AM_DEP1 and AM_DEP2 will call the above function in the beginning. Once the function confirms that the other procedure is not active, the current routine will be registered and executed. Registering will tag the necessary information in V$SESSION view.

create or replace procedure am_dep1 is 
  ..
begin 
  if not chk_dep_run('AM_DEP2') then
    dbms_output.put_line('AM_DEP2 is currently running');
    return;
  end if;

  dbms_application_info.set_module('AM_DEP1', 'running apps1'); --register 
  -- continue executing the code.
  ..
  dbms_application_info.set_module(null, null);  --unregister
end; 


create or replace procedure am_dep2 is 
  ..
begin 
  if not chk_dep_run('AM_DEP1') then
    dbms_output.put_line('AM_DEP1 is currently running');
    return;
  end if;

  dbms_application_info.set_module('AM_DEP2', 'running apps2');  --register 
  -- continue executing the code.
  ..
 dbms_application_info.set_module(null, null);  --unregister
end; 

Conclusion

Use of DBMS_APPLICATION_INFO depends a lot on the coding. Flexibility is provided to put any type of character string in the dictionary table columns and then refer to it from the application. Proper coding standards should be implemented for using this feature as per the application requirement. Call the package at the beginning of all application sessions to set the appropriate information. The package may be called multiple times to update the dictionary during the lifetime of the session.

» See All Articles by Columnist Amar Kumar Padhi



Oracle Archives

Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 




Latest Forum Threads
Oracle Forum
Topic By Replies Updated
Oracle Data Mining: Classification jan.hasller 0 July 5th, 07:19 AM
Find duplicates - Unique IDs Lava 5 July 2nd, 08:30 AM
no matching unique or primary key rcanter 1 April 25th, 12:32 PM
Update values of one table based on condition of values in other table using Trigger Gladiator 3 February 29th, 06:01 PM


















Thanks for your registration, follow us on our social networks to keep up-to-date