github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sqlbase/locking.proto (about)

     1  // Copyright 2020 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  syntax = "proto2";
    12  package cockroach.sql.sqlbase;
    13  option go_package = "sqlbase";
    14  
    15  // ScanLockingStrength controls the row-level locking mode used by scans.
    16  //
    17  // Typically, SQL scans read sequential keys from the key-value layer without
    18  // acquiring any locks. This means that two scans by different transactions will
    19  // not conflict and cause one of the two transactions to block the other. This
    20  // is usually desirable, as it increases concurrency between readers.
    21  //
    22  // However, there are cases where a SQL scan would like to acquire locks on each
    23  // of the keys that it reads to more carefully control concurrent access to the
    24  // data that it reads. The prototypical example of this is a scan that is used
    25  // to fetch the initial value of a row that its transction intends to later
    26  // update. In this case, it would be beneficial to acquire a lock on the row
    27  // during the initial scan instead of waiting until the mutation to acquire a
    28  // lock. This prevents the row from being modified between the scan and the
    29  // mutation. It also prevents situations that can lead to deadlocks.
    30  //
    31  // Locking modes have differing levels of strength, growing from "weakest" to
    32  // "strongest" in the order that the variants are presented in the enumeration.
    33  // The "stronger" a locking mode, the more protection it provides for the lock
    34  // holder but the more restrictive it is to concurrent transactions attempting
    35  // to access the same keys.
    36  //
    37  // The following matrix presents the compatibility of locking strengths with one
    38  // another.
    39  //
    40  //  +-------------------+---------------+-----------+-------------------+------------+
    41  //  |                   | FOR_KEY_SHARE | FOR_SHARE | FOR_NO_KEY_UPDATE | FOR_UPDATE |
    42  //  +-------------------+---------------+-----------+-------------------+------------+
    43  //  | FOR_KEY_SHARE     |               |           |                   |      X     |
    44  //  +-------------------+---------------+-----------+-------------------+------------+
    45  //  | FOR_SHARE         |               |           |         X         |      X     |
    46  //  +-------------------+---------------+-----------+-------------------+------------+
    47  //  | FOR_NO_KEY_UPDATE |               |     X     |         X         |      X     |
    48  //  +-------------------+---------------+-----------+-------------------+------------+
    49  //  | FOR_UPDATE        |       X       |     X     |         X         |      X     |
    50  //  +-------------------+---------------+-----------+-------------------+------------+
    51  //
    52  // A transaction can hold conflicting locks on the same row, but two different
    53  // transactions can never hold conflicting locks on the same row. Once acquired,
    54  // a lock is held until the end of the transaction.
    55  enum ScanLockingStrength {
    56    // FOR_NONE represents the default - no row-level locking.
    57    FOR_NONE = 0;
    58  
    59    // FOR_KEY_SHARE represents the FOR KEY SHARE row-level locking mode.
    60    //
    61    // The mode behaves similarly to FOR SHARE, except that the lock is weaker:
    62    // SELECT FOR UPDATE is blocked, but not SELECT FOR NO KEY UPDATE. A
    63    // key-shared lock blocks other transactions from performing DELETE or any
    64    // UPDATE that changes the key values, but not other UPDATE, and neither does
    65    // it prevent SELECT FOR NO KEY UPDATE, SELECT FOR SHARE, or SELECT FOR KEY
    66    // SHARE.
    67    //
    68    // The locking mode was introduced into Postgres as an alternative to FOR
    69    // SHARE to improve concurrency between foreign key validation scans, which
    70    // acquire FOR KEY SHARE locks, and UPDATEs to existing rows, which acquire
    71    // FOR NO KEY UPDATE locks.
    72    //
    73    // NOTE: FOR_KEY_SHARE is currently ignored. No locks are acquired.
    74    FOR_KEY_SHARE = 1;
    75  
    76    // FOR_SHARE represents the FOR SHARE row-level locking mode.
    77    //
    78    // The mode behaves similarly to FOR NO KEY UPDATE, except that it acquires a
    79    // shared lock rather than exclusive lock on each retrieved row. A shared lock
    80    // blocks other transactions from performing UPDATE, DELETE, SELECT FOR UPDATE
    81    // or SELECT FOR NO KEY UPDATE on these rows, but it does not prevent them
    82    // from performing SELECT FOR SHARE or SELECT FOR KEY SHARE.
    83    //
    84    // NOTE: FOR_SHARE is currently ignored. No locks are acquired.
    85    FOR_SHARE = 2;
    86  
    87    // FOR_NO_KEY_UPDATE represents the FOR NO KEY UPDATE row-level locking mode.
    88    //
    89    // The mode behaves similarly to FOR UPDATE, except that the lock acquired is
    90    // weaker: this lock will not block SELECT FOR KEY SHARE commands that attempt
    91    // to acquire a lock on the same rows. This lock mode is also acquired by any
    92    // UPDATE that does not acquire a FOR UPDATE lock.
    93    //
    94    // The locking mode was introduced into Postgres as an alternative to FOR
    95    // UDPATE to improve concurrency between foreign key validation scans, which
    96    // acquire FOR KEY SHARE locks, and UPDATEs to existing rows, which acquire
    97    // FOR NO KEY UPDATE locks.
    98    //
    99    // NOTE: FOR_NO_KEY_UPDATE is currently promoted to FOR_UPDATE.
   100    FOR_NO_KEY_UPDATE = 3;
   101  
   102    // FOR_UPDATE represents the FOR UPDATE row-level locking mode.
   103    //
   104    // The mode causes the rows retrieved by the scan to be locked as though for
   105    // update. This prevents them from being locked, modified or deleted by other
   106    // transactions until the current transaction ends. That is, other
   107    // transactions that attempt UPDATE, DELETE, SELECT FOR UPDATE, SELECT FOR NO
   108    // KEY UPDATE, SELECT FOR SHARE or SELECT FOR KEY SHARE of these rows will be
   109    // blocked until the current transaction ends. Conversely, SELECT FOR UPDATE
   110    // will wait for a concurrent transaction that has run any of those commands
   111    // on the same row, and will then lock and return the updated row (or no row,
   112    // if the row was deleted).
   113    //
   114    // NOTE: FOR_UPDATE is currently implemented by acquiring lock.Exclusive locks
   115    // on each key scanned.
   116    FOR_UPDATE = 4;
   117  }
   118    
   119  // ScanLockingWaitPolicy controls the policy used by scans for dealing with rows
   120  // being locked by FOR UPDATE/SHARE clauses.
   121  enum ScanLockingWaitPolicy {
   122    // BLOCK represents the default - wait for the lock to become available.
   123    BLOCK = 0;
   124  
   125    // SKIP represents SKIP LOCKED - skip rows that can't be locked.
   126    //
   127    // NOTE: SKIP is not currently implemented and does not make it out of the SQL
   128    // optimizer without throwing an error.
   129    SKIP  = 1;
   130  
   131    // ERROR represents NOWAIT - raise an error if a row cannot be locked.
   132    //
   133    // NOTE: ERROR is not currently implemented and does not make it out of the
   134    // SQL optimizer without throwing an error.
   135    ERROR = 2;
   136  }