diff --git a/docs/RFCS/20171024_select_for_update.md b/docs/RFCS/20171024_select_for_update.md
new file mode 100644
index 000000000000..7b33b19f60a1
--- /dev/null
+++ b/docs/RFCS/20171024_select_for_update.md
@@ -0,0 +1,458 @@
+- Feature Name: Support `SELECT FOR UPDATE`
+- Status: postponed
+- Start Date: 2017-10-17
+- Authors: Rebecca Taft
+- RFC PR: [#19577](https://github.com/cockroachdb/cockroach/pull/19577)
+- Cockroach Issue: [#6583](https://github.com/cockroachdb/cockroach/issues/6583)
+
+# Summary
+
+This RFC is postponed because it seems that, given CockroachDB's model of concurrency control,
+it is not possible to implement the functionality that users would expect for `SELECT ... FOR UPDATE`.
+None of the implementation alternatives we have examined would fully replicate the semantics that Postgres
+provides, and there is a risk that customers would try to use the feature without fully
+understanding the pitfalls. The details are described below in the [Drawbacks](#drawbacks) and
+[Alternatives](#alternatives) sections. We may revisit this feature if there is sufficient demand from
+customers, or if we can prove that there is a significant benefit to using `SELECT ... FOR UPDATE`
+for certain applications.
+
+Original Summary: Support the `SELECT ... FOR UPDATE` SQL syntax, which locks rows returned by the `SELECT`
+statement. This pessimistic locking feature prevents concurrent transactions from updating
+any of the locked rows until the locking transaction commits or aborts. This is useful for
+enforcing consistency when running in `SNAPSHOT` mode, and may be useful for avoiding deadlocks
+when running in `SERIALIZABLE` mode. Several potential customers have asked for this feature,
+and it would also get us closer to feature parity with Postgres. The proposed implementation is
+to set row-level "dummy" intents by transforming the `SELECT ... FOR UPDATE` query tree to
+include an `updateNode`.
+
+# Motivation
+
+As described in [Issue #6583](https://github.com/cockroachdb/cockroach/issues/6583),
+`SELECT ... FOR UPDATE` is not standard SQL, but many databases now support it, including
+Postgres. Thus the primary motivation for this feature is compatibility with existing code.
+Several third party products such as the [Quartz Scheduler](http://www.quartz-scheduler.org),
+[OpenJPA](http://openjpa.apache.org) and [Liquibase](http://www.liquibase.org)
+also rely on this feature, preventing some potential customers from switching to CockroachDB.
+
+In some cases, `SELECT ... FOR UPDATE` is required to maintain correctness when running CockroachDB
+in `SNAPSHOT` mode. In particular, `SELECT ... FOR UPDATE` can be used to prevent write skew anomalies.
+Write skew anomalies occur when two concurrent transactions read an overlapping set of
+rows but update disjoint sets of rows. Since the transactions each operate on private snapshots of
+the database, neither one will see the updates from the other.
+
+The [Wikipedia entry on Snapshot Isolation](https://en.wikipedia.org/wiki/Snapshot_isolation) has a
+useful concrete example:
+
+> ... imagine V1 and V2 are two balances held by a single person, Phil. The bank will allow either
+V1 or V2 to run a deficit, provided the total held in both is never negative (i.e. V1 + V2 ≥ 0).
+Both balances are currently $100. Phil initiates two transactions concurrently, T1 withdrawing $200
+from V1, and T2 withdrawing $200 from V2. .... T1 and T2 operate on private snapshots of the database:
+each deducts $200 from an account, and then verifies that the new total is zero, using the other account
+value that held when the snapshot was taken. Since neither update conflicts, both commit successfully,
+leaving V1 = V2 = -$100, and V1 + V2 = -$200.
+
+It is possible to prevent this scenario from happening in `SNAPSHOT` mode by using `SELECT ... FOR UPDATE`.
+For example, if each transaction calls something like:
+`SELECT * FROM accounts WHERE acct_name = 'V1' OR acct_name = 'V2' FOR UPDATE` at the start of the transaction,
+one of the transactions would be blocked until the "winning" transaction commits and releases the locks.
+At that point, the "losing" transaction would be able to see the update from the winner, so it would not deduct
+$200. Therefore, using `SELECT ... FOR UPDATE` lets users obtain some of the performance benefits of using `SNAPSHOT`
+isolation instead of `SERIALIZABLE`, without paying the price of write skew anomalies.
+
+`SELECT ... FOR UPDATE` is not needed for correctness when running in `SERIALIZABLE` mode,
+but it may still be useful for controlling lock ordering and avoiding deadlocks. For example,
+consider the following schedule:
+
+```
+T1: Starts transaction
+T2: Starts transaction
+T1: Updates row A
+T2: Updates row B
+T1: Wants to update row B (blocks)
+T2: Wants to update row A (deadlock)
+```
+
+This sort of scenario can happen in any database that tries to maintain some level of correctness.
+It is especially common in databases that use pessimistic two-phased locking (2PL) since transactions
+must acquire shared locks for reads in addition to exclusive locks for writes. But deadlocks like the
+one shown above also happen in databases that use MVCC like PostgreSQL and CockroachDB, since writes must
+acquire locks on all rows that will be updated. Postgres, CockroachDB, and many other systems detect deadlocks by
+identifying cycles in a "waits-for" graph, where nodes represent transactions, and directed edges represent
+transactions waiting on each other to release locks (or write intents). In Postgres, if a cycle (deadlock) is detected,
+transactions will be selectively aborted until the cycle(s) are removed. CockroachDB forces one of the transactions
+in the cycle to be "pushed", which generally has the effect of aborting at least one transaction. CockroachDB
+can perform this detection and push almost instantaneously after the conflict happens, so "deadlocks" in CockroachDB
+are less disruptive than in Postgres, where deadlock detection can take up to a second. Some other systems
+use a timeout mechanism, where transactions will abort after waiting a certain amount of time to acquire a lock.
+In all cases, the deadlock causes delays and/or aborted transactions.
+
+`SELECT ... FOR UPDATE` will help avoid deadlocks by allowing transactions to acquire all of their locks
+(lay down intents in CockroachDB) up front. For example, the above schedule would change to the following:
+
+```
+T1: Starts transaction
+T2: Starts transaction
+T1: Locks rows A and B
+T1: Updates row A
+T2: Wants to lock rows A and B (blocks)
+T1: Updates row B
+T1: Commits
+T2: Locks rows A and B
+T2: Updates row B
+T2: Updates row A
+T2: Commits
+```
+
+Since both transactions attempted to lock rows A and B at the start of the transaction, the deadlock was prevented.
+Acquiring all locks (or laying down write intents) up front allows the database to lock rows in a consistent order
+(even if they are updated in a different order), thus preventing deadlocks.
+
+Many implementations of this feature also include options to control whether or not to wait on locks.
+`SELECT ... FOR UPDATE NOWAIT` is one option, which causes the query to return an error if it is
+unable to immediately lock all target rows. This is useful for latency-critical situations,
+and could also be useful for auto-retrying transactions in CockroachDB. `SELECT ... FOR UPDATE SKIP LOCKED`
+is another option, which returns only the rows that could be locked immediately, and skips over the others.
+This option returns an inconsistent view of the data, but may be useful for cases when multiple
+workers are trying to process data in the same table as if it were a queue of tasks.
+The default behavior of `SELECT ... FOR UPDATE` is for the transaction to block if some of the
+target rows are already locked by another transaction. Note that it is not possible to use the
+`NOWAIT` and `SKIP LOCKED` modifiers without `FOR { UPDATE | SHARE | ... }`.
+
+The first implementation of `FOR UPDATE` in CockroachDB will not include `NOWAIT` or `SKIP LOCKED` options.
+It seems that some users want these features, but many would be satisfied with `FOR UPDATE` alone.
+As of this writing we are not aware of any commonly used third-party products that use these options.
+
+# Guide-level explanation
+
+The [Postgres Documentation](https://www.postgresql.org/docs/current/static/sql-select.html#sql-for-update-share)
+describes this feature as it is supported by Postgres. As shown, the syntax of the locking clause has the form
+
+```
+FOR lock_strength [ OF table_name [, ...] ] [ NOWAIT | SKIP LOCKED ]
+```
+
+where `lock_strength` can be one of
+
+```
+UPDATE
+NO KEY UPDATE
+SHARE
+KEY SHARE
+```
+
+For our initial implementation in CockroachDB, we will likely simplify this syntax to
+
+```
+FOR UPDATE
+```
+
+i.e., no variation in locking strength, no specified tables, and no options for avoiding
+waiting on intents. Using `FOR UPDATE` will result in laying intents on the rows returned by the `SELECT`
+query. Note that it only lays intents for rows that already exist; preventing inserts matching
+the `SELECT` query is not desired. As described above, this feature alone is useful because it helps
+maintain correctness when running CockroachDB in `SNAPSHOT` mode (avoiding write skew), and serves
+as a tool for optimization (avoiding deadlocks) when running in `SERIALIZABLE` mode.
+
+For example, consider the following transaction:
+
+
+```
+BEGIN;
+
+SELECT * FROM employees WHERE name = 'John Smith' FOR UPDATE;
+
+...
+
+UPDATE employees SET salary = 50000 WHERE name = 'John Smith';
+
+COMMIT;
+```
+
+This code will lay intents on the rows of all employees named John Smith at the beginning of the transaction,
+preventing other concurrent transactions from simultaneously updating those rows.
+As a result, the `UPDATE employees ...` statement at the end of the transaction will not need
+to lay any additional intents. Note that `FOR UPDATE` will have no effect if it is used in a
+stand-alone query that is not part of any transaction.
+
+One important difference between CockroachDB and Postgres relates to transaction priorities. In CockroachDB,
+if there is a conflict and the second transaction has a higher priority, the first transaction will be
+pushed out of the way -- even if it has laid down intents already. This would apply to transactions with
+`SELECT ... FOR UPDATE`, just as it would for any other transaction.
+
+# Reference-level explanation
+
+This section provides more detail about how and why the CockroachDB implementation of
+the locking clause will differ from Postgres.
+
+With the current model of CockroachDB, it is not possible to support the locking strengths
+`NO KEY UPDATE` or `KEY SHARE` because
+these options require locking at a sub-row granularity. It is also not clear that CockroachDB can support
+`SHARE`, because there is currently no such thing as a "read intent". `UPDATE` can be supported by
+marking the affected rows with dummy write intents.
+
+By default, if `FOR UPDATE` is used in Postgres without specifying tables
+(without the `OF table_name [, ...]` clause),
+Postgres will lock all rows returned by the `SELECT` query. The `OF table_name [, ...]` clause
+enables locking only the rows in the specified tables. To lock different tables with different
+strengths or different options, Postgres users can string multiple locking clauses together.
+For example,
+
+```
+SELECT * from employees e, departments d, companies c
+WHERE e.did = d.id AND d.cid = c.id
+AND c.name = `Cockroach Labs`
+FOR UPDATE OF employees SKIP LOCKED
+FOR SHARE OF departments NOWAIT
+```
+locks rows in the `employees` table that satisfy the join condition with an exclusive lock,
+and skips over rows that are already locked by another transaction.
+It also locks rows in the `departments` table that satisfy the join condition with a shared lock,
+and returns an error if it cannot lock all of the rows immediately. It does not lock
+the `companies` table.
+
+Implementing this flexibility in CockroachDB for use of different tables and different options
+may be excessively complicated, and it's not clear that our customers actually need
+it. To avoid spending too much time on this, as mentioned above, we will probably just implement the most
+basic functionality in which clients use `FOR UPDATE` to lay intents on the rows returned by the query.
+Initially we won't include the `SKIP LOCKED` or `NOWAIT` options, but it may be worth implementing
+these at some point.
+
+At the moment `FOR UPDATE` is disabled for use in views (there will not be an error, but it will
+be ignored). This is similar to the way `ORDER BY` and `LIMIT` are handled in views. See comment from @a-robinson in
+[data_source.go:getViewPlan()](https://github.com/cockroachdb/cockroach/blob/5a6b4312a972b74b0af5de53dfdfb204dc0fd6d7/pkg/sql/data_source.go#L680).
+As described in the comment, the outer `Select` AST node is currently being stripped out of the view plan.
+If `ORDER BY` and `LIMIT` are enabled later by including the entire `Select`, `FOR UPDATE` would come for free.
+Postgres supports all of these options in views, since it supports any `SELECT` query, and re-runs
+the query each time the view is used. CockroachDB should do the same.
+
+With the (temporary) exception of views, `FOR UPDATE` should propagate throughout the query plan
+as expected. If `FOR UPDATE` only occurs in a subquery, the rows locked are those returned by the subquery
+to the outer query (unless the optimizer reduces the amount of data scanned in the subquery). For example,
+`SELECT * FROM employees e, (SELECT * FROM departments FOR UPDATE) d WHERE e.did = d.id`
+would only lock rows in the departments table. If the `FOR UPDATE` occurs on the outer `SELECT`, however,
+all rows returned by the query will be locked.
+
+If the number of intents exceeds `maxIntents` as defined in `txn_coord_sender.go`
+(default 100,000), the transaction will be rejected. This is similar to the way updates work,
+and will prevent users from using `SELECT FOR UPDATE` with queries that would result in a full table
+scan. If we need to reduce this number later we can add a new setting just for `SELECT FOR UPDATE`.
+
+One issue that is not discussed in detail in the Postgres documentation is the order in which
+locks are acquired. Acquiring locks in a consistent order is an important tool to prevent deadlocks
+from occuring. For the CockroachDB implementation of `FOR UPDATE`, we will not implement the feature
+in DistSQL at this time (DistSQL does not currently support writes), so our implementation
+will most likely produce a consistent ordering of write intents (we currently have no evidence
+to the contrary). It is difficult to guarantee a particular ordering, however, since the implementation
+of the local execution engine may change in the future to take advantage of parallel processing. Likewise,
+if `FOR UPDATE` is supported later in DistSQL, ordering will be more difficult to guarantee.
+
+## Detailed design
+
+There are a number of changes that will need to be implemented in the SQL layer in order to
+support `FOR UPDATE`.
+
+- Update the parser to support the syntax in `SELECT` statements.
+- Add checks to ensure that `FOR UPDATE` cannot be used with `GROUP BY`, `HAVING`, `WINDOW`, `DISTINCT`,
+ `UNION`, `INTERSECT`, `EXCEPT`, or in contexts where returned rows cannot be clearly identified with
+ individual table rows; for example it cannot be used with aggregation. Postgres also disallows
+ `FOR UPDATE` with all of these query types.
+- Possibly add additional checks for the first implementation to limit `SELECT FOR UPDATE` queries to
+ "simple" queries where the primary key must be used in the `WHERE` clause, and the predicate must be either `==` or `IN`.
+- Modify the query tree so that the top level `renderNode` is transformed to an `updateNode` which sets each selected
+ column value to itself and returns the selected rows (e.g., `UPDATE table SET a = a RETURNING a`). If needed,
+ a `sortNode` and/or `limitNode` can be applied above the `updateNode` in the query tree.
+
+Note that none of this design involves DistSQL. At the moment DistSQL does not support writes,
+so it would not make sense to support `FOR UPDATE`.
+
+## Drawbacks
+
+We have decided to postpone this feature because it is not clear that the proposed solution
+(or any of the alternatives discussed below) would meet customer needs.
+
+Some potential customers (such as those using the Quartz Scheduler) use `SELECT FOR UPDATE`
+as if it were an advisory lock; they never actually update the rows selected by the `SELECT FOR UPDATE`
+statement, so the only purpose of the lock is to prevent other concurrent transactions from accessing some
+shared resource during the transaction. Although the proposed solution of laying intents
+will achieve this isolation, it will result in many aborted transactions. For example, consider a
+transaction `T1` with a lower timestamp than another transaction `T2`. If `T1` tries to access rows
+already marked with an intent by `T2`, `T1` will block until `T2` commits or aborts, and then `T1` will
+abort with a retryable error. Most existing codebases using `SELECT FOR UPDATE` are probably not equipped
+to handle these retryable errors because other databases would not cause transactions to abort in this scenario.
+
+The key motivation described above for using `SELECT FOR UPDATE` in `SERIALIZABLE` mode is to control
+lock ordering so as to minimize transaction aborts. Due to the way concurrency control works in
+CockroachDB, however, `SELECT FOR UPDATE` is still likely to cause many aborts (as described in the previous
+paragraph). Postgres also recommends against using this feature in `SERIALIZABLE` mode, since it is not necessary
+for correctness, and can degrade performance by causing disk accesses to set locks. Additionally, although `FOR UPDATE`
+can prevent deadlocks if used judiciously, it can also cause deadlocks if not every transaction
+sets intents in the same order. Since `FOR UPDATE` results in transactions setting more intents
+for a longer period of time, the chance of collision is higher. There may be some benefit to using `FOR UPDATE`
+with high-contention workloads since it would cause conflicting transactions to fail earlier and do less work
+before aborting, but we would need to run some tests to validate this (perhaps by running benchmarks
+with high-contention workloads). If we do eventually implement this feature, we should probably discourage customers
+from using `FOR UPDATE` in `SERIALIZABLE` mode unless they have good reasons to use it.
+
+It's also not clear that this feature is worth implementing for use in `SNAPSHOT` mode.
+As mentioned above, the primary motivation for this feature is compatibility with existing code.
+Simply running in `SERIALIZABLE` mode is (probably) a better way of avoiding write skew than `SNAPSHOT`
++`FOR UPDATE`.
+
+Given the above drawbacks, we have decided it is not worth the effort to implement `SELECT FOR UPDATE` at
+this time. But if we do implement it in the future, one way to make sure customers avoid the pitfalls
+is to create an "opt-in" setting for using this feature. By default, using `FOR UPDATE` would throw an
+error and direct users to view the documentation. Only users who explicitly opt in by updating their cluster
+or session settings would be able to use the feature. We could also add an option to either use the feature
+with intents or as a no-op (see the [Isolation Upgrade](#no-op) alternative below). Adding options adds
+complexity, however.
+
+If we implement this feature, we should probably start with only `FOR UPDATE`, and not
+include other features (e.g., `NOWAIT`, `SKIP LOCKED`, etc). It will be a lot of work to implement
+all of the features supported by Postgres, and it is probably not worth our time since it's not clear
+these features will actually get used. We can easily add them later if needed.
+
+In the mean time, customers who really need explicit locking functionality can emulate the
+feature by executing something like `UPDATE x SET y=y WHERE y=y`. Executing this command at
+the start of a transaction would effectively set intents on all of the rows in table `x`.
+
+## Rationale and Alternatives
+
+The proposed solution is to "lock" rows by writing dummy write intents on each row as part
+of an update operation. However, there are a couple of alternative implementations worth
+considering, specifically row-level intents set as part of a scan operation,
+range-level intents, and isolation ugrade.
+
+### Row-level intents set during scan
+
+Laying intents as part of an `UPDATE` operation could be expensive for simple `SELECT FOR UPDATE`
+queries since it requires multiple requests to the KV layer. The first KV request performs the scan
+operation, and subsequent requests update each row to lay an intent. For simple queries, a less
+expensive approach would be to lay intents directly during the scan operation.
+
+This approach has a few downsides, however. First, it would be more work to implement since
+it would require updates to the KV API to include new messages (e.g., ScanForUpdate and ReverseScanForUpdate).
+These new messages would require updates to the KV and storage layers to mimic processing of Scan and ReverseScan
+and set dummy write intents on every row touched.
+
+As described in [issue #6583](https://github.com/cockroachdb/cockroach/issues/6583),
+> Implementing this would touch a lot of different parts of the code. No part is individually too
+tricky, but there are a lot of them (`git grep -i reversescan` will give you an idea of the scope).
+The bulk of the changes would consist of implementing new ScanForUpdate and ReverseScanForUpdate
+calls in the KV API. These would work similarly to regular scans, but A) would be flagged as read/write
+commands instead of read-only and B) after performing the scan, they'd use MVCCPut to write back the
+values that were just read (that's not the most efficient way to do things, but I think it's the right
+way to start since it will have the right semantics without complicating the backwards-compatibility
+story). Then the SQL layer would use these instead of plan Scan/ReverseScan when `FOR UPDATE` has been
+requested.
+
+There was some discussion in the issue about whether we really needed new API calls, but
+the consensus was that making it possible to write on `Scan` requests would make debugging a nightmare.
+
+This approach would also require a change in the SQL layer to handle the case when a `SELECT FOR UPDATE`
+query would only scan a secondary index and not touch the primary key (PK) index. In this case,
+we would need to implicitly modify the query plan to add a join with the PK index so that intents
+would always be laid on the PK index. This would ensure that the `SELECT FOR UPDATE` query would prevent
+concurrent transactions from updating the corresponding rows, since updates must always lay
+intents on the PK index.
+
+Another downside is that in many cases this approach would set intents on more rows than returned by the
+`SELECT`, since most predicates are not applied until after the scan is completed. This should not affect
+correctness in terms of consistency or isolation, but could affect performance if there is high contention.
+For example, if the first `SELECT` statement in the [employees transaction shown above](#employees_transaction)
+were `SELECT * FROM employees WHERE name like '%Smith' FOR UPDATE;`, CockroachDB would set intents on
+all of the rows in the `employees` table because it's not possible to determine from the predicate
+which key spans are affected. This lack of precision would be an issue for any predicate that
+does not directly translate to particular key spans. Furthermore, since this translation may not be obvious
+to users, they could easily write queries that would result in full-table scans by accident.
+
+In contrast, Postgres (generally) locks exactly the rows returned by the query, and no more. There are a few
+examples given in the [documentation](https://www.postgresql.org/docs/current/static/sql-select.html#sql-for-update-share)
+where that's not the case. For example, `SELECT ... LIMIT 5 OFFSET 5 FOR UPDATE` may
+lock up to 10 rows even though only 5 rows are returned.
+
+### Range-level intents
+
+One alternative to row-level intents is to set an intent on an entire Range if the `SELECT` statement
+would return the majority of rows in the range. This is similar to the approach
+suggested by the [Revert Command RFC](https://github.com/cockroachdb/cockroach/pull/16294).
+
+The advantage of setting intents on entire ranges is that it would significantly improve the performance
+for large scans compared to setting intents on individual rows. The downside is that
+this feature is not yet implemented, so it would be significantly more effort than using
+simple row-level intents. (It was actually deemed to be too complex and all-interfering in the
+[Revert Command RFC](https://github.com/cockroachdb/cockroach/pull/16294), which is why that
+RFC is now closed.) It's also not clear that customers would use `FOR UPDATE` with
+large ranges, so this may be an unneeded performance optimization. Furthermore,
+setting an intent on the entire range based on the predicate could result in "locking" rows that should
+not be observable by the `SELECT`. For instance, if the transaction performing the
+`SELECT FOR UPDATE` query over some range is at a lower timestamp than a later `INSERT`
+within that range, the `FOR UPDATE` should not apply to the newly written row.
+This issue is probably not any worse than the other problems with locking precision described above,
+though.
+
+One advantage of implementing range-level intents is that we could reuse this feature
+for other applications such as point-in-time recovery. The details of the proposed implementation
+as well as other possible applications are described in the [Revert Command RFC](https://github.com/cockroachdb/cockroach/pull/16294).
+However, in the interest of getting something working sooner rather than later,
+I believe row-level intents make more sense at this time.
+
+### Isolation upgrade
+
+Another alternative approach is to avoid setting any intents whatsoever. Instead, the `SELECT FOR UPDATE`
+would be a no-op for `SERIALIZABLE` transactions, and the database would automatically upgrade the isolation
+of a `SNAPSHOT` transaction to `SERIALIZABLE` when a `SELECT FOR UPDATE` is used. The advantage of this
+approach is its simplicity: the work required to support this feature would be minimal. Additionally,
+it would avoid the issues of lock precision and poor performance that exist in the other proposed solutions.
+Furthermore, it would successfully prevent write skew in
+`SNAPSHOT` transactions, which is a key reason many customers might want to use `SELECT FOR UPDATE`
+in the first place.
+
+The downside is that it may not be what our customers expect. It would not allow customers to control
+lock ordering, which as described above is one feature of `SELECT FOR UPDATE` that savvy users can employ to
+prevent deadlocks and other conflicts. Some users may also have reason to lock rows that they don't intend to
+update, and they will have no way to do that with this solution.
+
+### Alternatives to FOR UPDATE
+
+So far this RFC has assumed that we want to implement some form of the `FOR UPDATE`
+SQL syntax. However, there are many other types of locks provided by Postgres, and
+it's possible that one of these other options would be a better choice for our customers.
+
+1. Table Level Locks:
+ Postgres provides eight different types of table level locks: `ACCESS SHARE, ROW SHARE,`
+ `ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE,` and `ACCESS EXCLUSIVE`.
+ These locks can be acquired explicity using the `LOCK` command, but they are also implicitly
+ acquired by different SQL statements. For example, a `SELECT` command (without `FOR UPDATE`)
+ implicitly acquires the `ACCESS SHARE` lock on every table it accesses. This prevents concurrent
+ calls to `DROP TABLE, TRUNCATE,` etc. on the same table, since those commands must acquire
+ an `ACCESS EXCLUSIVE` lock, wchich conflicts with `ACCESS SHARE`. See the
+ [PG docs](https://www.postgresql.org/docs/current/static/explicit-locking.html#locking-tables)
+ for the full list of conflicts.
+2. Row Level Locks:
+ There are four different types of row level locks: `UPDATE, NO KEY UPDATE, SHARE, KEY SHARE`.
+ As described above, these can be acquired explicitly with the `SELECT ... FOR locking_strength`
+ command. This RFC has been focused on `SELECT ... FOR UPDATE`, but the other three options
+ are available in Postgres to allow more concurrent accesses. The `UPDATE` (or under certain
+ circumstances `NO KEY UPDATE`) locks are also acquired implicitly by `UPDATE` and `DELETE` commands.
+ See the [PG docs](https://www.postgresql.org/docs/current/static/explicit-locking.html#locking-rows)
+ for more details.
+3. Advisory Locks:
+ Advisory locks are used to lock application-level resources, identified either by a single 64-bit key
+ value or two 32-bit key values. It is up to the application programmer to ensure that locks are
+ acquired and released at the correct points in time to ensure application-level resources are
+ properly protected. Postgres provides numerous options for advisory locks. They can be:
+ - Session-level (must be explicitly unlocked) or transaction-level (will be unlocked automatically at commit/abort)
+ - Shared or exclusive
+ - Blocking or non-blocking (e.g. `pg_try_advisory_lock` is non-blocking)
+
+ All of the different advisory lock functions are listed in the [PG docs](https://www.postgresql.org/docs/current/static/functions-admin.html#functions-advisory-locks)
+
+There are valid arguments for using each of these different lock types in different applications.
+However, I do not think that either table-level locks or advisory locks will be a good
+substitue for our customers that require explicit row-level locks.
+Table-level locks are not a good substitue for `FOR UPDATE` and the other row-level locks
+because they are too coarse-grained and will cause unnecessary performance degradation.
+Advisory locks place too much responsibility on the application developer(s) to ensure that the
+appropriate lock is always acquired before accessing a given row. This doesn't mean we
+shouldn't support advisory locks, but I don't think we should force developers to use them
+in place of explicit row-level locks.