home *** CD-ROM | disk | FTP | other *** search
/ Winzipper / Winzipper_ISO.iso / programming / oracle7 7.2 / DB / UTIL72 / DBMSLOCK.SQL < prev    next >
Encoding:
Text File  |  1995-05-09  |  15.1 KB  |  356 lines

  1. rem 
  2. rem $Header: dbmslock.sql 7020100.1 94/09/23 22:14:39 cli Generic<base> $ 
  3. rem 
  4. Rem  Copyright (c) 1991 by Oracle Corporation 
  5. Rem    NAME
  6. Rem      dbmslock.sql - locking routines provided by Oracle
  7. Rem    DESCRIPTION
  8. Rem      See below
  9. Rem    RETURNS
  10. Rem
  11. Rem    NOTES
  12. Rem     The procedural option is needed to use this facility.
  13. Rem
  14. Rem     Lockids from 2000000000 to 2147483647 are reserved for products
  15. Rem     supplied by Oracle:
  16. Rem
  17. Rem       Package                     Lock id range
  18. Rem       =================================================
  19. Rem       dbms_alert                  2000000000-2000002041
  20. Rem       dbms_alert                  2000002042-2000003063
  21. Rem
  22. Rem    MODIFIED   (MM/DD/YY)
  23. Rem     adowning   03/29/94 -  merge changes from branch 1.10.710.1
  24. Rem     adowning   02/02/94 -  split file into public / private binary files
  25. Rem     rkooi      12/03/92 -  change comments 
  26. Rem     rkooi      11/25/92 -  return 5 instead of 6 per spec 
  27. Rem     rkooi      11/24/92 -  check for nulls 
  28. Rem     rkooi      11/18/92 -  add comments 
  29. Rem     rkooi      08/20/92 -  comments and cleanup 
  30. Rem     rkooi      06/29/92 -  add some comments 
  31. Rem     rkooi      05/30/92 -  fix timeout problems 
  32. Rem     rkooi      04/30/92 -  add some comments 
  33. Rem     rkooi      04/25/92 -  misc change 
  34. Rem     rkooi      04/12/92 -  Creation 
  35.  
  36. Rem This script must be run as user SYS
  37.  
  38. REM ************************************************************
  39. REM THIS PACKAGE MUST NOT BE MODIFIED BY THE CUSTOMER.  DOING SO
  40. REM COULD CAUSE INTERNAL ERRORS AND CORRUPTIONS IN THE RDBMS.
  41. REM FOR INSTANCE, THE PSD* ROUTINES MUST NOT BE CALLED DIRECTLY
  42. REM BY ANY CLIENT AND MUST REMAIN PRIVATE TO THIS PACKAGE.
  43. REM ************************************************************
  44.  
  45. create or replace package dbms_lock is
  46.  
  47.   ------------
  48.   --  OVERVIEW
  49.   --
  50.   --  These routines allow the user to request, convert and release locks.
  51.   --  The locks are managed by the rdbms lock management services.  All
  52.   --  lock ids are prepended with the 'UL' prefix so that they cannot
  53.   --  conflict with DBMS locks.  These locks will show up in the SQL*DBA
  54.   --  lock monitor screen and in the appropriate fixed views.
  55.   --
  56.   --  Deadlock detection is performed on these locks.
  57.   --
  58.   --  Locks are automatically released when the session terminates.
  59.   --  It is up to the clients to agree on the use of these locks.  The
  60.   --  lock identifier is a number in the range of 0 to 1073741823.  
  61.   --
  62.   --  The allocate_unique call can be used to allocate a unique lockid
  63.   --  (in the range of 1073741824 to 1999999999) given a lock name.  This is
  64.   --  provided since it may be easier for applications to coordinate
  65.   --  their use of locks based on lock names rather than lock numbers.
  66.   --  The first session to call allocate_unique with a new lock name will
  67.   --  cause a unique lockid to be generated and stored in the
  68.   --  dbms_lock_allocated table.  Subsequent calls (usually by other
  69.   --  sessions) will return the lockid previously generated.  A lock name
  70.   --  will be associated with the returned lockid for at least
  71.   --  'expiration_secs' (defaults to 10 days) past the last call to
  72.   --  allocate_unique with the given lock name.  After this time, the row
  73.   --  in the dbms_lock_allocated table for this lock name may be deleted
  74.   --  in order to recover space.  Allocate_unique performs a commit.
  75.   --
  76.   --  A sleep procedure is also provided which causes the caller to sleep
  77.   --  for the given interval.
  78.  
  79.  
  80.   ------------------------------------------------
  81.   --  SUMMARY OF SERVICES PROVIDED BY THIS PACKAGE
  82.   --
  83.   --  allocate_unique - allocate a unique lock given a name
  84.   --  request          - request a lock of given mode
  85.   --  convert          - convert lock from one mode to another
  86.   --  releas          - release the lock
  87.   --  sleep          - sleep for the specified time
  88.  
  89.  
  90.   ---------------
  91.   --  LIMITATIONS
  92.   --
  93.   --  The implementation does not support large numbers of locks efficiently.
  94.   --  A few hundred locks per session should be the limit.
  95.  
  96.  
  97.   ------------
  98.   --  SECURITY
  99.   --
  100.   --  There may be OS-specific limits on the maximum number of total
  101.   --  locks available.  You will need to consider this when using locks,
  102.   --  or making this package available to users.  You may wish to only
  103.   --  grant execute to those users or roles that you trust.  An
  104.   --  alternative is to create a cover package for this package which
  105.   --  limits those locks used.  Then, instead of granting execute on this
  106.   --  package to public, grant execute on the cover package
  107.   --  only to specific users.  A cover package might look like this:
  108.   --
  109.   --  create package lock_100_to_200 is
  110.   --    nl_mode  constant integer := 1;
  111.   --    ss_mode  constant integer := 2;
  112.   --    sx_mode  constant integer := 3;
  113.   --    s_mode   constant integer := 4;
  114.   --    ssx_mode constant integer := 5;
  115.   --    x_mode   constant integer := 6;
  116.   --    maxwait  constant integer := 32767;
  117.   --    function request(id in integer,
  118.   --                     lockmode in integer default x_mode, 
  119.   --                     timeout in integer default maxwait,
  120.   --                     release_on_commit in boolean default FALSE)
  121.   --      return integer;
  122.   --    function convert(id in integer;
  123.   --                     lockmode in integer, 
  124.   --                     timeout in number default maxwait)
  125.   --      return integer;
  126.   --    function release(id in integer) return integer;
  127.   --  end;
  128.   --  create package body lock_100_to_200 is
  129.   --  begin
  130.   --    function  request(id in integer,
  131.   --                     lockmode in integer default x_mode, 
  132.   --                     timeout in integer default maxwait,
  133.   --                     release_on_commit in boolean default FALSE)
  134.   --      return integer is
  135.   --    begin
  136.   --      if id < 100 or id > 200 then
  137.   --        raise_application_error(-20000,'Lock id out of range');
  138.   --      endif;
  139.   --      return dbms_lock.request(id, lockmode, timeout, release_on_commit);
  140.   --    end;
  141.   --    function convert(id in integer,
  142.   --                     lockmode in integer, 
  143.   --                     timeout in number default maxwait)
  144.   --      return integer is
  145.   --    begin
  146.   --      if id < 100 or id > 200 then
  147.   --        raise_application_error(-20000,'Lock id out of range');
  148.   --      endif;
  149.   --      return dbms_lock.convert(id, lockmode, timeout);
  150.   --    end;
  151.   --    function release(id in integer) return integer is
  152.   --    begin
  153.   --      if id < 100 or id > 200 then
  154.   --        raise_application_error(-20000,'Lock id out of range');
  155.   --      endif;
  156.   --      return dbms_lock.release(id);
  157.   --    end;
  158.   --  end;
  159.   --  
  160.   --  Grant execute on the lock_100_to_200 package to those users who
  161.   --  are allowed to use locks in the 100-200 range.  Don't grant execute
  162.   --  on package dbms_lock to anyone.  The lock_100_200 package
  163.   --  should be created as sys.
  164.   --
  165.   --  The "dbms_session.is_role_enabled" procedure could also be used
  166.   --  in a cover package to enforce security.
  167.  
  168.   ---------------------
  169.   --  SPECIAL CONSTANTS
  170.   --
  171.   nl_mode  constant integer := 1;
  172.   ss_mode  constant integer := 2;    -- Also called 'Intended Share'
  173.   sx_mode  constant integer := 3;    -- Also called 'Intended Exclusive'
  174.   s_mode   constant integer := 4;
  175.   ssx_mode constant integer := 5;
  176.   x_mode   constant integer := 6;
  177.   --  These are the various lock modes (nl -> "NuLl", ss -> "Sub Shared",
  178.   --  sx -> "Sub eXclusive", s -> "Shared", ssx -> "Shared Sub eXclusive",
  179.   --  x -> "eXclusive").
  180.   --
  181.   --  A sub-share lock can be used on an aggregate object to indicate that 
  182.   --  share locks are being aquired on sub-parts of the object.  Similarly, a
  183.   --  sub-exclusive lock can be used on an aggregate object to indicate
  184.   --  that exclusive locks are being aquired on sub-parts of the object.  A
  185.   --  share-sub-exclusive lock indicates that the entire aggregate object
  186.   --  has a share lock, but some of the sub-parts may additionally have
  187.   --  exclusive locks.
  188.   --
  189.   --  Lock Compatibility Rules:
  190.   --  When another process holds "held", an attempt to get "get" does
  191.   --  the following:
  192.   --
  193.   --  held  get->  NL   SS   SX   S    SSX  X
  194.   --  NL           SUCC SUCC SUCC SUCC SUCC SUCC
  195.   --  SS           SUCC SUCC SUCC SUCC SUCC fail
  196.   --  SX           SUCC SUCC SUCC fail fail fail
  197.   --  S            SUCC SUCC fail SUCC fail fail
  198.   --  SSX          SUCC SUCC fail fail fail fail
  199.   --  X            SUCC fail fail fail fail fail
  200.   --
  201.   maxwait  constant integer := 32767;
  202.   -- maxwait means to wait forever
  203.  
  204.  
  205.   ----------------------------
  206.   --  PROCEDURES AND FUNCTIONS
  207.   --
  208.   procedure allocate_unique(lockname in varchar2, 
  209.                 lockhandle out varchar2,
  210.                 expiration_secs in integer default 864000);
  211.   --  Given a name, generate a unique lockid for this lock.  This procedure
  212.   --    always performs a 'commit'.
  213.   --  Input parameters:
  214.   --    lockname    
  215.   --      name of lock to generate unique lockid for.  If this name already
  216.   --      has been assigned a lockid, then return a handle to that lockid.
  217.   --      Otherwise generate a new lockid and return a handle to it.
  218.   --      WARNING: Do not use locknames beginning with 'ORA$'; these names
  219.   --      are reserved for products supplied by Oracle Corporation.  The
  220.   --      name can be up to 128 bytes, and is case-sensitive.
  221.   --    expiration_secs
  222.   --      number of seconds after an 'allocate_unique' is last performed on
  223.   --      this lock name that this lock is subject to cleanup (i.e.,
  224.   --      deleting from the dbms_lock_allocated table).  Defaults to 10
  225.   --      days.
  226.   --  Output parameters:
  227.   --    lockhandle
  228.   --      The actual lockid is not returned, rather a handle to it is
  229.   --      returned.  Use this handle in subsequent calls to request,
  230.   --      convert and release. Up to 128 bytes are returned.  A handle
  231.   --      is used to reduce the chance that a programming error can
  232.   --      accidentally create an incorrect but valid lockid.  This will
  233.   --      provide better isolation between different applications that are
  234.   --      using this package.
  235.   --
  236.   --      All sessions using a lockhandle returned by a call to
  237.   --      allocate_unique using the same name will be referring to the same
  238.   --      lock.  Different sessions may have different lockhandles for the
  239.   --      same lock, so lockhandles should not be passed from one session
  240.   --      to another.
  241.   --
  242.   --      The lockid's generated by allocate_unique are between 1073741824
  243.   --      and 1999999999, inclusive.
  244.   --
  245.   --      This routine will always do a commit.
  246.   --
  247.   --  Errors raised:
  248.   --    -20000, ORU-10003: Unable to find or insert lock <lockname>
  249.   --        into catalog dbms_lock_allocated.
  250.   
  251.   function  request(id in integer,
  252.                     lockmode in integer default x_mode, 
  253.                     timeout in integer default maxwait,
  254.                     release_on_commit in boolean default FALSE)
  255.     return integer;
  256.   function  request(lockhandle in varchar2,
  257.                     lockmode in integer default x_mode, 
  258.                     timeout in integer default maxwait,
  259.                     release_on_commit in boolean default FALSE)
  260.     return integer;
  261.   --  Request a lock with the given mode. Note that this routine is
  262.   --    overloaded based on the type of its first argument.  The
  263.   --    appropriate routine is used based on how it is called.
  264.   --    If a deadlock is detected, then an arbitrary session is
  265.   --    chosen to receive deadlock status.
  266.   --    ***NOTE*** When running both multi-threaded server (dispatcher) AND
  267.   --    parallel server, a multi-threaded "shared server" will be
  268.   --    bound to a session during the time that any locks are held.
  269.   --    Therefore the "shared server" will not be shareable during this time.
  270.   --  Input parameters:
  271.   --    id
  272.   --      From 0 to 1073741823.  All sessions that use the same number will
  273.   --      be referring to the same lock. Lockids from 2000000000 to
  274.   --      2147483647 are accepted by this routine.  Do not use these as 
  275.   --      they are reserved for products supplied by Oracle Corporation.
  276.   --    lockhandle
  277.   --      Handle returned by call to allocate_unique.
  278.   --    lockmode
  279.   --      See lockmodes and lock compatibility table above
  280.   --    timeout
  281.   --      Timeout in seconds.  If the lock cannot be granted within this
  282.   --      time period then the call returns a value of 1.  Deadlock
  283.   --      detection is performed for all "non-small" values of timeout.
  284.   --    release_on_commit 
  285.   --      If TRUE, then release on commit or rollback, otherwise keep until
  286.   --      explicitly released or until end-of-session.  If a transaction
  287.   --      has not been started, it will be.
  288.   --  Return value:
  289.   --    0 - success
  290.   --    1 - timeout
  291.   --    2 - deadlock
  292.   --    3 - parameter error
  293.   --    4 - already own lock specified by 'id' or 'lockhandle'
  294.   --    5 - illegal lockhandle
  295.   --
  296.   function convert(id in integer, 
  297.                    lockmode in integer, 
  298.                    timeout in number default maxwait)
  299.     return integer;
  300.   function convert(lockhandle in varchar2, 
  301.                    lockmode in integer, 
  302.                    timeout in number default maxwait)
  303.     return integer;
  304.   --  Convert a lock from one mode to another. Note that this routine is
  305.   --    overloaded based on the type of its first argument.  The
  306.   --    appropriate routine is used based on how it is called.
  307.   --    If a deadlock is detected, then an arbitrary session is
  308.   --    chosen to receive deadlock status.
  309.   --  Input parameters:
  310.   --    id
  311.   --      From 0 to 1073741823.
  312.   --    lockhandle
  313.   --      Handle returned by call to allocate_unique.
  314.   --    lockmode
  315.   --      See lockmodes and lock compatibility table above.
  316.   --    timeout
  317.   --      Timeout in seconds.  If the lock cannot be converted within this
  318.   --      time period then the call returns a value of 1.  Deadlock
  319.   --      detection is performed for all "non-small" values of timeout.
  320.   --  Return value:
  321.   --    0 - success
  322.   --    1 - timeout
  323.   --    2 - deadlock
  324.   --    3 - parameter error
  325.   --    4 - don't own lock specified by 'id' or 'lockhandle'
  326.   --    5 - illegal lockhandle
  327.   --
  328.   function release(id in integer) return integer;
  329.   function release(lockhandle in varchar2) return integer;
  330.   --  Release a lock previously aquired by 'request'. Note that this routine
  331.   --    is overloaded based on the type of its argument.  The
  332.   --    appropriate routine is used based on how it is called.
  333.   --  Input parameters:
  334.   --    id
  335.   --      From 0 to 1073741823.
  336.   --  Return value:
  337.   --    0 - success
  338.   --    3 - parameter error
  339.   --    4 - don't own lock specified by 'id' or 'lockhandle'
  340.   --    5 - illegal lockhandle
  341.   --
  342.   procedure sleep(seconds in number);
  343.   --  Suspend the session for the specified period of time.
  344.   --  Input parameters:
  345.   --    seconds
  346.   --      In seconds, currently the maximum resolution is in hundreths of 
  347.   --      a second (e.g., 1.00, 1.01, .99 are all legal and distinct values).
  348.  
  349. end;
  350. /
  351.  
  352. drop public synonym dbms_lock
  353. /
  354. create public synonym dbms_lock for sys.dbms_lock
  355. /
  356.