LOCKING Request Modifier - Teradata Database

SQL Data Manipulation Language

Product
Teradata Database
Release Number
15.00
Language
English (United States)
Last Update
2018-09-28
dita:id
B035-1146
lifecycle
previous
Product Category
Teradata® Database

LOCKING Request Modifier

Purpose  

Locks a database, table, view, or row‑hash at the specified severity level, overriding the default locking level the system places on a database, table, view, or row‑hash in response to a request.

Syntax  

where:

 

Syntax Element …

Specifies …

DATABASE
TABLE
VIEW

an optional keyword to indicate the type of object to lock.

ROW

an optional keyword specifying the row‑hash level for locking in accordance with the defining statement (see “Using LOCKING ROW” on page 418).

database_name

the name of the database or user to be locked.

table_name

the name of the base table to be locked.

view_name

the name of the view to be locked.

FOR
IN

an introduction to the type of lock to be placed.

ACCESS

READ

SHARE

WRITE

EXCLUSIVE

CHECKSUM

the severity, or granularity, of the lock to be placed.

SHARE is a deprecated synonym for READ.

CHECKSUM is only available for embedded SQL and stored procedure applications with updatable cursors.

OVERRIDE

to permit a READ lock for a single‑table SELECT operation when a rollback on an underlying base table in the query was cancelled using the Recovery Manager utility CANCEL ROLLBACK ON TABLE command. See Utilities.

You can only specify the OVERRIDE option with a READ lock request.

MODE

an optional keyword.

NOWAIT

that if the indicated lock cannot be obtained, the request should be aborted.

Specify this option for situations in which it is not desirable to have a request wait for resources, and possibly tie up resources another request could use, while waiting.

SQL_request

a valid SQL request.

You cannot specify LOCKING with the CALL statement.

If SQL_request is null, then the only effect of LOCK is to lock the specified object.

This specification is mandatory for row‑hash‑level locking, but optional for database-, base table-, and view‑level locking.

ANSI Compliance

LOCKING is a Teradata extension to the ANSI SQL:2011 standard.

Other SQL dialects support similar non‑ANSI standard statements with names such as the following:

  • LOCK TABLE
  • Required Privileges

    None.

    Applicability

    Besides its common use with DML statements, you can also specify the LOCKING modifier with most DDL, DCL, SHOW and HELP statements. In particular, it can be used with CREATE INDEX and COLLECT STATISTICS to override the default locking severities to prevent deadlocks. LOCKING is also frequently used within view definitions.

    You cannot specify a LOCKING request modifier with a CALL request.

    Locking Severities

    You can specify the following lock severities. For additional information about locking, see “Locking and Transaction Processing” in SQL Request and Transaction Processing.

     

    Lock Type

    Description

    ACCESS

    Permits selection of data from a base table that can be locked for write access by other users.

    The data selected using an ACCESS lock can be inconsistent because the data may be modified concurrently with the request. Therefore, you should only use this lock for casual inspection of data.

    Placing an ACCESS lock requires the SELECT privilege on the specified object.

    READ
    SHARE

    Ensures data consistency during a read operation such as a SELECT request.

    Multiple users can concurrently hold a READ lock on a base table. As long as a READ lock is in place, no modification of the object is allowed.

    Placing a READ lock requires the SELECT privilege on the specified object.

    SHARE is a deprecated synonym for READ.

    WRITE

    Enables a single user to modify data.

    As long as the WRITE lock is in place, all other users are excluded from viewing or modifying the object except readers who are viewing data using an ACCESS lock.

    Until a WRITE lock is released, no new READ locks are permitted on the locked object.

    Placing a WRITE lock requires an UPDATE, INSERT, or DELETE privilege on the specified object.

    EXCLUSIVE

    Excludes all other users.

    This is the most restrictive lock.

    EXCLUSIVE locks are rarely used except to make structural changes to a database.

    Placing an EXCLUSIVE lock on a database object requires the DROP privilege on that object.

    CHECKSUM

    Used only with updatable cursors in embedded SQL and stored procedures.

    When Explicit Locking Is Necessary

    The system automatically places locks on database objects each time an SQL request is performed. Therefore, the use of the LOCKING modifier is seldom necessary. Explicit user‑specified locks are only useful when you need to override the automatic locking specified by the Optimizer and placed by the Lock Manager.

    Cancelling a Lock

    An operation can wait for a requested lock indefinitely unless you specify the NOWAIT option. If you are working interactively and do not want to wait for a lock, you can issue the BTEQ .ABORT command to cancel the transaction.

    LOCKING Request Modifier Use With Different DML Statements

    The following table indicates associations between individual SQL DML statements and lock upgrades and downgrades at the row‑hash, view, base table, and database object levels:

     

    This LOCKING modifier severity specification …

    Is available for this SQL DML statement …

    EXCLUSIVE

    DELETE
    INSERT
    MERGE
    SELECT
    SELECT AND CONSUME
    UPDATE

    WRITE

    SELECT

    READ

    SELECT

    ACCESS

    SELECT

    The reason that the only modifier for the DELETE, INSERT, MERGE, UPDATE, and SELECT AND CONSUME statements is LOCKING FOR EXCLUSIVE is that the default lock severity for these statements is WRITE. You cannot downgrade a WRITE lock for these statements because doing so would compromise the integrity of the database. Because the SELECT statement does not change data, and therefore its actions cannot compromise database integrity, you are permitted to change its default locking severity to any other severity.

    You can specify lower locking severity levels than are listed in this table, but if you do, Teradata Database ignores them.

    For details about locking levels, locking severities, and the relationship between them, see SQL Request and Transaction Processing.

    Positioning Explicit Lock Requests

    When you need to place an explicit lock, the LOCKING modifier must precede the SQL request that is to be affected by the requested lock.

    The system places the requested lock on the object referenced by the LOCKING modifier for the duration of the transaction containing the modified SQL request. If the transaction is a single‑statement request, then the specified lock is only in effect for the duration of the request.

    Using Locks with NULL SQL Requests

    If the LOCKING modifier is followed by a null SQL request (see “Null” on page 299), the only effect of the modifier is to lock the specified object. While the LOCKING modifier can be used with a null request, it is best to use LOCKING with a user-generated transaction or as part of a multistatement request.

    Using LOCKING ROW

    Note that LOCKING ROW does not generally lock a single row, but rather all rows that hash to a specific value. It is a row hash lock, not a row lock.

    The LOCKING ROW modifier cannot be used to lock multiple row‑hashes. If you specify LOCKING ROW FOR ACCESS with multiple row‑hashes, the lock is converted to LOCKING TABLE FOR ACCESS, but a WRITE or EXCLUSIVE row‑hash lock severity is not transferred to a table‑level lock. If a LOCKING ROW FOR WRITE severity is not applicable, the default table‑level lock severity is maintained.

    A single value in an IN clause is accepted as a valid row‑hash lock specification.

    The use of LOCKING ROW prevents possible deadlocks occurring when two simultaneous primary index SELECTs are followed by an UPDATE, DELETE, or INSERT on the same row.

    For example:

    User A:

         BEGIN TRANSACTION;
     
         SELECT y 
         FROM t 
         WHERE x=1;
     
         UPDATE t 
         SET y=0 
         WHERE x=1;
     
         END TRANSACTION;

    User B:

         BEGIN TRANSACTION;
     
         SELECT z 
         FROM t 
         WHERE x=1;
     
         UPDATE t 
         SET z=0 
         WHERE x=1;
     
         END TRANSACTION;

    The Lock Manager assigns a row‑hash‑level READ lock when a simple SELECT request is made using a UPI, NUPI, or USI.

    The User A UPDATE request ROW FOR WRITE lock request waits for the User B ROW OR READ lock to be released. The ROW FOR READ lock is not released because the User B UPDATE request ROW FOR WRITE lock request is also waiting for the User A ROW FOR READ lock to be released. Previously, this deadlock was avoided by using the LOCKING TABLE modifier:

         BEGIN TRANSACTION;
     
         LOCKING TABLE t FOR WRITE 
         SELECT z 
         FROM t 
         WHERE x = 1;
     
         UPDATE ...
     
         END TRANSACTION;

    Locking an entire base table across all AMPS is undesirable, and the use of LOCKING ROW here prevents the need to lock an entire base table across all AMPs.

    The following example illustrates the use of LOCKING ROW:

    User A:

         BEGIN TRANSACTION;
     
         LOCKING ROW FOR WRITE 
         SELECT y 
         FROM t 
         WHERE x=1; 
     
         UPDATE t 
         SET y=0 
         WHERE x=1
     
         END TRANSACTION;

    User B:

         BEGIN TRANSACTION;
     
         LOCKING ROW FOR WRITE 
         SELECT z 
         FROM t 
         WHERE x=1;
     
         UPDATE t 
         SET z=0 
         WHERE x=1;

    No deadlock occurs because the User B LOCKING ROW FOR WRITE request is blocked by the User A LOCKING ROW FOR WRITE. The User B LOCKING ROW FOR WRITE request completes when the User A END TRANSACTION statement is complete.

    The system honors a LOCKING ROW modifier request only in the following situations:

  • For single‑table retrievals, using primary or unique secondary index searches.
  • When specified with a SELECT request, because the LOCKING ROW modifier picks up the row‑hash to be locked from the SELECT request.
  • To upgrade any of the following locks:
  •  

    Upgrade from this lock …

    To this lock …

  • READ
  • SHARE
  • WRITE

  • READ
  • SHARE
  • EXCLUSIVE

    WRITE

    EXCLUSIVE

    The system does not honor a LOCKING ROW modifier request in the following situations:

  • Where a lock on the target base table is already in place.
  • Where an aggregate/DISTINCT/GROUP BY operation is part of the SELECT request.
  • To downgrade a lock from READ to ACCESS, once that lock is in place.
  • If no row‑hash lock is in place already, an ACCESS lock can be set instead of a default READ row‑hash lock.

    Deadlock occurs when two primary index SELECTs are followed by primary index UPDATES and the SELECTs are on different row‑hashes. This is because a primary index update requires a table‑level WRITE lock on the target base table.

    For example:

    User A:

         BEGIN TRANSACTION;
     
         LOCKING ROW WRITE 
         SELECT x 
         FROM t 
         WHERE x = 1; (x is UPI, NUPI, or USI)
     
         UPDATE t 
         SET x=2 
         WHERE x=1;

    User B:

         BEGIN TRANSACTION;
     
         LOCKING ROW WRITE 
         SELECT x 
         FROM t 
         WHERE x=2;
     
         UPDATE t 
         SET x=1 
         WHERE x=2;

    The User B SELECT ROW WRITE lock is not queued behind the User A transaction because it has a different row‑hash access. Deadlock occurs because the User A table‑level lock request waits on the User B row‑hash lock, while the User B table‑level lock request waits on the User A row‑hash lock.

    Multiple Locks

    Multiple LOCKING modifiers can precede a request if it is necessary to lock more than one object at the same time, for example:

         LOCKING TABLE employee FOR ACCESS
         LOCKING TABLE department FOR ACCESS
         SELECT name, loc
         FROM employee, department
         WHERE (empno=mgrno);  

    Referencing a Locked Object

    The object that is locked by the LOCKING modifier does not have to be referenced in a subsequent SQL request.

    A lock can be executed separately from the SQL request that it precedes. Therefore, a LOCKING modifier must reference the object on which a lock is being placed. The objects referenced in the SQL request have no effect on the execution of a LOCKING modifier.

    When a LOCKING modifier references a view, the specified lock is applied to all underlying base tables. For example, if a view refers to tables t1 and t2, then a lock on that view would apply to both tables.

    LOCKING DATABASE is the only way to lock a database or user.

    Specify the Keyword For the Object To Be Locked

    Be sure to specify the keyword for the object (database, table, view, or row‑hash) that is to be locked.

    For example, if a database and table are both named accntrec, then you could specify the following form:

         LOCKING TABLE accntrec FOR ACCESS 
         SELECT * 
         FROM accntrec;

    If the TABLE keyword had not been included, the lock would have been placed on the accntrec database.

    Locks and Views

    A LOCKING modifier can be specified in a view definition. When a view is defined with a LOCKING modifier, the specified lock is placed on the underlying base table set each time the view is referenced in an SQL request.

    For more information on defining views, see CREATE VIEW and CREATE RECURSIVE VIEW in SQL Data Definition Language.

    When the Request and View Referenced Include LOCKING Request Modifiers

    Although views are often created to enforce a LOCKING FOR ACCESS rule, any user can override the LOCKING FOR ACCESS by specifying a LOCKING FOR READ request modifier on the view. For example:

         REPLACE VIEW vprod.ad_me_inf AS
         LOCKING TABLE prod.ad_me_inf FOR ACCESS
         SELECT ad_me_id, ad_me_dsc_tx
         FROM prod.ad_me_inf;

    If you do an EXPLAIN on the following query, the ACCESS lock can be seen in statement 1.

         SELECT COUNT(*) 
         FROM vprod.ad_me_inf;

    If you do an EXPLAIN on the following query, you can see a READ lock in statement 1 of the report.

         LOCKING TABLE vprod.ad_me_inf FOR READ
         SELECT COUNT (*) 
         FROM vprod.ad_me_inf;

    This behavior could be considered undesirable because the LOCKING FOR ACCESS request modifier can be overridden by anyone at any time. However, some users find this to be useful and depend on being able to override lock clauses in views by placing a lock in the request.

    READ Locks and Cancelled Rollback Operations

    When you use the RcvManager utility to cancel a transaction rollback, the system marks the base table on which the rollback was cancelled as nonvalid. As a result, the table cannot be updated. With some restrictions, you can inspect the rows of the non‑valid base table if you specify a LOCKING FOR READ OVERRIDE modifier.

    The following rules document the restrictions on the use of a LOCKING FOR READ OVERRIDE modifier:

  • You can only read from a single base table using this modifier. Attempts to perform multitable operations return an error.
  • You can specify LOCKING FOR READ OVERRIDE for any single base table, whether a rollback has been cancelled on that table or not.
  • The Optimizer only uses indexes to read base valid base tables. If you use LOCKING FOR READ OVERRIDE to access a non‑valid table, then the system always uses a full‑table scan.
  • Determining Which Locks Are Set

    Use the EXPLAIN request modifier with an SQL request to determine what locks are set when the request is executed.

    Example  

    The following LOCKING clause can be used to select data from the employee table while it is being modified:

         LOCKING TABLE personnel.employee FOR ACCESS
         SELECT name, salary 
         FROM employee 
         WHERE salary < 25000 ;

    This query might do any of the following things.

  • Return rows whose data can be updated or deleted an instant later by a concurrent operation initiated by another user who has obtained a WRITE lock.
  • Omit rows that are undergoing a concurrent insert operation.
  • Include rows that were never permanently in the base table, because a transaction that was being used to insert new rows was aborted and its new rows backed out.
  • Example  

    The system deals properly with the synchronization of base data rows and index subtable rows. However, an ACCESS lock can allow inconsistent results even when secondary indexes are used in conditional expressions because index constraints are not always rechecked against the data row.

    For example, suppose a column named qualify_accnt is defined as a secondary index for a base table named accnt_rec as it does in the following request:

         LOCKING TABLE accnt_rec FOR ACCESS
         SELECT accnt_no, qualify_accnt 
         FROM accnt_rec 
         WHERE qualify_accnt = 1587;

    The request could return:

         accnt_no     qualify_accnt 
         ‑‑‑‑-‑‑‑     -‑‑‑‑‑‑‑‑‑‑‑‑
             1761              4214

    In this case, the value 1587 was found in the secondary index subtable and the corresponding data row was selected and returned. However, the data for account 1761 had been changed by another user while the retrieval was in process. This is referred to as a dirty read. See SQL Request and Transaction Processing.

    Anomalous results like these are possible even if the data is changed only momentarily by a transaction that is ultimately aborted. The ACCESS lock is most useful to those who simply want an overview of data and are not concerned with consistency.

    Example : LOCKING ROW

    This example shows the proper use of a rowhash lock.

         CREATE TABLE customer (
           cust_id INTEGER,
           phone   INTEGER, 
           fax     INTEGER, 
           telex   INTEGER) 
         PRIMARY INDEX (cust_id), 
         UNIQUE INDEX(fax), 
         INDEX(telex):
     
         CREATE TABLE sales (
           custcode INTEGER, 
           zip      INTEGER, 
           salesvol INTEGER);

    User A:

         BEGIN TRANSACTION;
     
         LOCKING ROW EXCLUSIVE
         SELECT phone 
         FROM customer 
         WHERE cust_id=12345;
     
         UPDATE customer 
         SET phone=3108292488 
         WHERE cust_id=12345;

    The User A EXCLUSIVE rowhash lock prevents another user from accessing the same row.

    In the following, the user A rowhash WRITE lock, in conjunction with LOCKING TABLE, prevents user B from accessing the same row:

    User A:

         BEGIN TRANSACTION;
     
         LOCKING TABLE sales FOR READ, 
         LOCKING ROW FOR WRITE 
         SELECT telex 
         FROM customer 
         WHERE fax=0;
     
         UPDATE customer 
         SET telex=0 
         WHERE fax=0;
     
         SELECT zip 
         FROM sales 
         WHERE custcode=111;
     
         SELECT salesvol 
         FROM sales 
         WHERE custcode=222;
         ...
     
         END TRANSACTION;

    User B:

         BEGIN TRANSACTION;
     
         LOCKING ROW FOR WRITE 
         SELECT * 
         FROM customer 
         WHERE cust_id=12345
         INSERT INTO customer (12345, 3108284422, 3108684231, 5555);
     
         END TRANSACTION;

    The User B LOCKING ROW FOR WRITE modifier waits until the User A transaction ends before it can be completed.

    Example : NOWAIT Option

    You have a request that you do not want to be placed in the lock queue if it cannot be serviced immediately. In this case, use the NOWAIT option. For example:

         LOCKING employee FOR READ NOWAIT
         SELECT employee_number,  last_name
         FROM employee
         WHERE department_number=401;
     
         *** Failure 7423 Object already locked and NOWAIT.
                Transaction Aborted. Statement# 1, Info =0

    Another request had employee locked, so you must resubmit the request.

         LOCKING employee FOR READ NOWAIT
         SELECT employee_number, last_name
         FROM employee
         WHERE department_number=401;
     
          *** Query completed. 7 rows found. 2 columns returned. 
          *** Total elapsed time was 1 second.
     
         employee_number  last_name 
         ---------------  --------------------
                    1003  Trader 
                    1004  Johnson 
                    1013  Phillips 
                    1002  Brown 
                    1010  Rogers 
                    1022  Machado 
                    1001  Hoover 

    This time, no locks were being held on employee, so the request completed successfully.

    Related Topics

  • SQL Request and Transaction Processing
  • Teradata Archive/Recovery Utility Reference
  • Utilities