home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / po7_win / db / rdbms71 / dbmslock.sql < prev    next >
Text File  |  1994-08-07  |  15KB  |  355 lines

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