8.4 中文镜像

MySQL 8.4 参考手册 · 中文镜像

正文为中文,英文原文默认隐藏。点击任意中文段落即可展开 / 收起对应英文原文。

打开官方英文原文 ↗

译文由机器翻译生成,仅供理解参考;有疑问请以官方英文原文为准。

MySQL 8.4 参考手册 / 15 条 SQL 语句 / 15.3 事务和锁定语句 / 15.3.6 LOCK TABLES 和 UNLOCK TABLES 语句
中文点击中文段落可显示 / 隐藏英文原文本页译文覆盖 100%

15.3.6 LOCK TABLES 和 UNLOCK TABLES 语句15.3.6 LOCK TABLES and UNLOCK TABLES Statements

LOCK {TABLE | TABLES}
    tbl_name [[AS] alias] lock_type
    [, tbl_name [[AS] alias] lock_type] ...

lock_type: {
    READ [LOCAL]
  | WRITE
}

UNLOCK {TABLE | TABLES}

MySQL 允许客户端会话显式获取表锁,以便与其他会话协作访问表,或在会话需要独占访问表期间防止其他会话修改表。一个会话只能为自己获取或释放锁。一个会话不能为另一个会话获取锁,也不能释放另一个会话持有的锁。MySQL enables client sessions to acquire table locks explicitly for the purpose of cooperating with other sessions for access to tables, or to prevent other sessions from modifying tables during periods when a session requires exclusive access to them. A session can acquire or release locks only for itself. One session cannot acquire locks for another session or release locks held by another session.

锁可以用于模拟事务,或在更新表时获得更高的速度。这在 表锁定限制和条件 中有更详细的说明。Locks may be used to emulate transactions or to get more speed when updating tables. This is explained in more detail in Table-Locking Restrictions and Conditions.

LOCK TABLES 明确为当前客户端会话获取表锁。表锁可以用于基本表或视图。您必须拥有 LOCK TABLES 权限,以及要锁定的每个对象的 SELECT 权限。LOCK TABLES explicitly acquires table locks for the current client session. Table locks can be acquired for base tables or views. You must have the LOCK TABLES privilege, and the SELECT privilege for each object to be locked.

对于视图锁定,LOCK TABLES 会将视图中使用的所有基本表添加到要锁定的表集合中,并自动锁定它们。对于任何被锁定视图的底层表,LOCK TABLES 会检查视图定义者(针对 SQL SECURITY DEFINER 视图)或调用者(针对所有视图)是否对表具有适当的权限。For view locking, LOCK TABLES adds all base tables used in the view to the set of tables to be locked and locks them automatically. For tables underlying any view being locked, LOCK TABLES checks that the view definer (for SQL SECURITY DEFINER views) or invoker (for all views) has the proper privileges on the tables.

如果使用 LOCK TABLES 显式锁定表,则触发器中使用的任何表也会被隐式锁定,如 LOCK TABLES 和触发器 所述。If you lock a table explicitly with LOCK TABLES, any tables used in triggers are also locked implicitly, as described in LOCK TABLES and Triggers.

如果你使用 LOCK TABLES 显式锁定一个表,任何与外键约束相关的表都会被隐式打开和锁定。对于外键检查,会在相关表上获取共享的只读锁(LOCK TABLES READ)。对于级联更新,会在涉及操作的相关表上获取无共享的写锁(LOCK TABLES WRITE)。If you lock a table explicitly with LOCK TABLES, any tables related by a foreign key constraint are opened and locked implicitly. For foreign key checks, a shared read-only lock (LOCK TABLES READ) is taken on related tables. For cascading updates, a shared-nothing write lock (LOCK TABLES WRITE) is taken on related tables that are involved in the operation.

UNLOCK TABLES 明确释放当前会话持有的任何表锁。LOCK TABLES 在获取新锁之前会隐式释放当前会话持有的任何表锁。UNLOCK TABLES explicitly releases any table locks held by the current session. LOCK TABLES implicitly releases any table locks held by the current session before acquiring new locks.

UNLOCK TABLES 的另一个用途是释放通过 FLUSH TABLES WITH READ LOCK 语句获得的全局读锁,这使您能够锁定所有数据库中的所有表。参见 第 15.7.8.3 节,“FLUSH 语句”。(如果您有如 Veritas 这样的文件系统能够进行快照,这是获得备份的一种非常方便的方式。)Another use for UNLOCK TABLES is to release the global read lock acquired with the FLUSH TABLES WITH READ LOCK statement, which enables you to lock all tables in all databases. See Section 15.7.8.3, “FLUSH Statement”. (This is a very convenient way to get backups if you have a file system such as Veritas that can take snapshots in time.)

LOCK TABLE 是 LOCK TABLES 的同义词;UNLOCK TABLE 是 UNLOCK TABLES 的同义词。LOCK TABLE is a synonym for LOCK TABLES; UNLOCK TABLE is a synonym for UNLOCK TABLES.

表锁仅能防止其他会话的不当读取或写入。持有 WRITE 锁的会话可以执行表级操作,例如 DROP TABLE 或 TRUNCATE TABLE。对于持有 READ 锁的会话,不允许执行 DROP TABLE 和 TRUNCATE TABLE 操作。A table lock protects only against inappropriate reads or writes by other sessions. A session holding a WRITE lock can perform table-level operations such as DROP TABLE or TRUNCATE TABLE. For sessions holding a READ lock, DROP TABLE and TRUNCATE TABLE operations are not permitted.

以下讨论仅适用于非TEMPORARY表。LOCK TABLES 对于TEMPORARY表是允许的(但会被忽略)。在创建该表的会话中可以自由访问该表,不管其他锁定是否生效。无需锁定,因为其他会话无法看到该表。The following discussion applies only to non-TEMPORARY tables. LOCK TABLES is permitted (but ignored) for a TEMPORARY table. The table can be accessed freely by the session within which it was created, regardless of what other locking may be in effect. No lock is necessary because no other session can see the table.

表锁获取Table Lock Acquisition

要在当前会话中获取表锁,请使用 LOCK TABLES 语句,它会获取元数据锁(参见 第 10.11.4 节,“元数据锁定”)。To acquire table locks within the current session, use the LOCK TABLES statement, which acquires metadata locks (see Section 10.11.4, “Metadata Locking”).

以下锁类型可用:The following lock types are available:

READ [LOCAL] 锁:READ [LOCAL] lock:

  • 持有该锁的会话可以读取表(但不能写入表)。The session that holds the lock can read the table (but not write it).

  • 多个会话可以同时获取表的 READ 锁。Multiple sessions can acquire a READ lock for the table at the same time.

  • 其他会话可以在未显式获取 READ 锁的情况下读取表。Other sessions can read the table without explicitly acquiring a READ lock.

  • LOCAL 修饰符允许其他会话在持锁期间执行不冲突的 INSERT 语句(并发插入)。 (参见 第 10.11.3 节,“并发插入”。)但是,如果在持锁期间要使用服务器外部的进程操作数据库,则不能使用 READ LOCAL。对于 InnoDB 表,READ LOCAL 与 READ 相同。The LOCAL modifier enables nonconflicting INSERT statements (concurrent inserts) by other sessions to execute while the lock is held. (See Section 10.11.3, “Concurrent Inserts”.) However, READ LOCAL cannot be used if you are going to manipulate the database using processes external to the server while you hold the lock. For InnoDB tables, READ LOCAL is the same as READ.

WRITE 锁:WRITE lock:

  • 持有该锁的会话可以读取和写入表。The session that holds the lock can read and write the table.

  • 只有持有锁的会话可以访问表。在释放锁之前,其他会话无法访问该表。Only the session that holds the lock can access the table. No other session can access it until the lock is released.

  • 其他会话对该表的锁请求在 WRITE 锁保持期间会被阻塞。Lock requests for the table by other sessions block while the WRITE lock is held.

WRITE 锁通常优先于 READ 锁,以确保更新尽快处理。这意味着,如果一个会话先获取了 READ 锁,然后另一个会话请求 WRITE 锁,随后的 READ 锁请求将等待,直到请求 WRITE 锁的会话获取并释放该锁。(当 max_write_lock_count 系统变量值较小时,该策略可能会有例外;参见 第 10.11.4 节,“元数据锁定”。)WRITE locks normally have higher priority than READ locks to ensure that updates are processed as soon as possible. This means that if one session obtains a READ lock and then another session requests a WRITE lock, subsequent READ lock requests wait until the session that requested the WRITE lock has obtained the lock and released it. (An exception to this policy can occur for small values of the max_write_lock_count system variable; see Section 10.11.4, “Metadata Locking”.)

如果 LOCK TABLES 语句由于其他会话对任何表持有锁而必须等待,则会阻塞,直到可以获取所有锁为止。If the LOCK TABLES statement must wait due to locks held by other sessions on any of the tables, it blocks until all locks can be acquired.

需要锁的会话必须在一个 LOCK TABLES 语句中获取所有锁。在获得的锁被保留期间,会话只能访问被锁定的表。例如,在接下来的语句序列中,尝试访问 t2,因为该请求未被锁定在 LOCK TABLES 语句:A session that requires locks must acquire all the locks that it needs in a single LOCK TABLES statement. While the locks thus obtained are held, the session can access only the locked tables. For example, in the following sequence of statements, an error occurs for the attempt to access t2 because it was not locked in the LOCK TABLES statement:

mysql> LOCK TABLES t1 READ;
mysql> SELECT COUNT(*) FROM t1;
+----------+
| COUNT(*) |
+----------+
|        3 |
+----------+
mysql> SELECT COUNT(*) FROM t2;
ERROR 1100 (HY000): Table 't2' was not locked with LOCK TABLES

INFORMATION_SCHEMA是例外。即使在会话中保存通过 LOCK TABLES。Tables in the INFORMATION_SCHEMA database are an exception. They can be accessed without being locked explicitly even while a session holds table locks obtained with LOCK TABLES.

你不能在同一查询中多次引用同一个锁名的表。改用别名,并为表和每个别名分别获得独立锁:You cannot refer to a locked table multiple times in a single query using the same name. Use aliases instead, and obtain a separate lock for the table and each alias:

mysql> LOCK TABLE t WRITE, t AS t1 READ;
mysql> INSERT INTO t SELECT * FROM t;
ERROR 1100: Table 't' was not locked with LOCK TABLES
mysql> INSERT INTO t SELECT * FROM t AS t1;

错误发生在第一个INSERT,因为锁定表有两个指向同名的引用。第二个 INSERT 成功,因为对表的引用使用了不同的名称。The error occurs for the first INSERT because there are two references to the same name for a locked table. The second INSERT succeeds because the references to the table use different names.

如果你的语句通过别名来指代表,你必须用相同的别名锁定表。不指定别名就无法锁定表:If your statements refer to a table by means of an alias, you must lock the table using that same alias. It does not work to lock the table without specifying the alias:

mysql> LOCK TABLE t READ;
mysql> SELECT * FROM t AS myalias;
ERROR 1100: Table 'myalias' was not locked with LOCK TABLES

反过来,如果你用别名锁住表,你必须在语句中引用该别名:Conversely, if you lock a table using an alias, you must refer to it in your statements using that alias:

mysql> LOCK TABLE t AS myalias READ;
mysql> SELECT * FROM t;
ERROR 1100: Table 't' was not locked with LOCK TABLES
mysql> SELECT * FROM t AS myalias;

表锁释放Table Lock Release

当会话持有的表锁被释放时,它们会同时释放。会话可以显式释放锁,或者在特定条件下隐式释放锁。When the table locks held by a session are released, they are all released at the same time. A session can release its locks explicitly, or locks may be released implicitly under certain conditions.

如果客户端会话的连接终止,无论是正常还是异常,服务器都会隐式释放会话持有的所有表锁(事务性和非事务性)。如果客户端重新连接,这些锁将不再生效。此外,如果客户端有一个活动事务,服务器在断开连接时会回滚该事务,如果重新连接发生,新会话将以自动提交启用开始。因此,客户端可能希望禁用自动重连。在启用自动重连的情况下,如果发生重连,客户端不会收到通知,但任何表锁或当前事务都将丢失。在禁用自动重连时,如果连接中断,下一个执行的语句将发生错误。客户端可以检测该错误并采取适当的操作,例如重新获取锁或重新执行事务。参见 自动重连控制。If the connection for a client session terminates, whether normally or abnormally, the server implicitly releases all table locks held by the session (transactional and nontransactional). If the client reconnects, the locks are no longer in effect. In addition, if the client had an active transaction, the server rolls back the transaction upon disconnect, and if reconnect occurs, the new session begins with autocommit enabled. For this reason, clients may wish to disable auto-reconnect. With auto-reconnect in effect, the client is not notified if reconnect occurs but any table locks or current transaction are lost. With auto-reconnect disabled, if the connection drops, an error occurs for the next statement issued. The client can detect the error and take appropriate action such as reacquiring the locks or redoing the transaction. See Automatic Reconnection Control.

Note

如果在锁定的表上使用 ALTER TABLE,表可能会被解锁。例如,如果尝试第二次进行 ALTER TABLE 操作,可能会出现错误 Table 'tbl_name' was not locked with LOCK TABLES。为处理此情况,应在第二次修改之前再次锁定表。另请参见 B.3.6.1 节,“ALTER TABLE 的问题”。If you use ALTER TABLE on a locked table, it may become unlocked. For example, if you attempt a second ALTER TABLE operation, the result may be an error Table 'tbl_name' was not locked with LOCK TABLES. To handle this, lock the table again prior to the second alteration. See also Section B.3.6.1, “Problems with ALTER TABLE”.

表锁与事务的交互Interaction of Table Locking and Transactions

LOCK TABLES 和 UNLOCK TABLES 与事务的使用交互如下:LOCK TABLES and UNLOCK TABLES interact with the use of transactions as follows:

  • LOCK TABLES 不是事务安全的,并且在尝试锁定表之前会隐式提交任何活动事务。LOCK TABLES is not transaction-safe and implicitly commits any active transaction before attempting to lock the tables.

  • UNLOCK TABLES 会隐式提交任何活动事务,但仅在使用 LOCK TABLES 获取表锁的情况下。例如,在以下语句集中,UNLOCK TABLES 释放全局读锁,但不提交事务,因为没有表锁生效:UNLOCK TABLES implicitly commits any active transaction, but only if LOCK TABLES has been used to acquire table locks. For example, in the following set of statements, UNLOCK TABLES releases the global read lock but does not commit the transaction because no table locks are in effect:

    FLUSH TABLES WITH READ LOCK;
    START TRANSACTION;
    SELECT ... ;
    UNLOCK TABLES;
    
  • 开始一个事务(例如,通过 START TRANSACTION)会隐式提交任何当前事务并释放现有表锁。Beginning a transaction (for example, with START TRANSACTION) implicitly commits any current transaction and releases existing table locks.

  • FLUSH TABLES WITH READ LOCK 获得全局读锁而非表锁,因此它不受 LOCK TABLES 和 UNLOCK TABLES 在表锁定和隐式提交方面。例如,START TRANSACTION 不会释放全局读锁。参见 第 15.7.8.3 节,“FLUSH 语句”。FLUSH TABLES WITH READ LOCK acquires a global read lock and not table locks, so it is not subject to the same behavior as LOCK TABLES and UNLOCK TABLES with respect to table locking and implicit commits. For example, START TRANSACTION does not release the global read lock. See Section 15.7.8.3, “FLUSH Statement”.

  • 其他隐式导致事务提交的语句不会释放现有的表锁。关于此类语句的列表,请参见 第 15.3.3 节,“导致隐式提交的语句”。Other statements that implicitly cause transactions to be committed do not release existing table locks. For a list of such statements, see Section 15.3.3, “Statements That Cause an Implicit Commit”.

  • 正确使用 LOCK TABLES 和 UNLOCK TABLES with transactional tables,例如 InnoDB 表,是以 SET autocommit = 0 (而不是START TRANSACTION),后面跟着 LOCK TABLES,也不是调用 UNLOCK TABLES直到你明确提交事务。例如,如果你需要写入表 t1,并从 表 t2,你可以这样做:The correct way to use LOCK TABLES and UNLOCK TABLES with transactional tables, such as InnoDB tables, is to begin a transaction with SET autocommit = 0 (not START TRANSACTION) followed by LOCK TABLES, and to not call UNLOCK TABLES until you commit the transaction explicitly. For example, if you need to write to table t1 and read from table t2, you can do this:

    SET autocommit=0;
    LOCK TABLES t1 WRITE, t2 READ, ...;
    ... do something with tables t1 and t2 here ...
    COMMIT;
    UNLOCK TABLES;
    

    当你调用 LOCK TABLES, InnoDB 内部会拿自己的表锁,MySQL 则会拿自己的表锁。InnoDB 在下一次提交时释放内部表锁,但 MySQL 要释放表锁,你必须调用 UNLOCK TABLES。你不应该设置 autocommit = 1,因为这样 InnoDB 会在调用 LOCK TABLES 后立即释放内部表锁,因此死锁很容易发生。InnoDB 如果autocommit = 1,以帮助旧应用避免不必要的死锁。When you call LOCK TABLES, InnoDB internally takes its own table lock, and MySQL takes its own table lock. InnoDB releases its internal table lock at the next commit, but for MySQL to release its table lock, you have to call UNLOCK TABLES. You should not have autocommit = 1, because then InnoDB releases its internal table lock immediately after the call of LOCK TABLES, and deadlocks can very easily happen. InnoDB does not acquire the internal table lock at all if autocommit = 1, to help old applications avoid unnecessary deadlocks.

  • ROLLBACK 不释放表锁。ROLLBACK does not release table locks.

锁定表和触发器LOCK TABLES and Triggers

如果你显式地用 LOCK TABLES,触发器中使用的任何表也被隐式锁定:If you lock a table explicitly with LOCK TABLES, any tables used in triggers are also locked implicitly:

  • 锁与显式获取的时间相同,LOCK TABLES 语句。The locks are taken as the same time as those acquired explicitly with the LOCK TABLES statement.

  • 触发器中使用的表的锁取决于该表是否仅用于读取。如果是这样,读取锁即可。否则,使用写锁。The lock on a table used in a trigger depends on whether the table is used only for reading. If so, a read lock suffices. Otherwise, a write lock is used.

  • 如果表显式锁定用于读取 LOCK TABLES,但写入时需要锁定,因为写入可能在触发器中被修改,则采用写锁而非读锁。(也就是说,由于该表出现在触发器中,需要隐式写锁,会导致表被显式读取锁请求转换为写锁请求。)If a table is locked explicitly for reading with LOCK TABLES, but needs to be locked for writing because it might be modified within a trigger, a write lock is taken rather than a read lock. (That is, an implicit write lock needed due to the table's appearance within a trigger causes an explicit read lock request for the table to be converted to a write lock request.)

假设你用以下语句锁定了两个表,t1 和 t2,使用如下语句:Suppose that you lock two tables, t1 and t2, using this statement:

LOCK TABLES t1 WRITE, t2 READ;

如果 t1 或 t2 有触发器,触发器中使用的表也会被锁定。假设 t1 的触发条件定义如下:If t1 or t2 have any triggers, tables used within the triggers are also locked. Suppose that t1 has a trigger defined like this:

CREATE TRIGGER t1_a_ins AFTER INSERT ON t1 FOR EACH ROW
BEGIN
  UPDATE t4 SET count = count+1
      WHERE id = NEW.id AND EXISTS (SELECT a FROM t3);
  INSERT INTO t2 VALUES(1, 2);
END;

LOCK TABLES 语句表明 t1 和 t2 是因为它们出现在语句中而被锁定,t3 和 t4 被锁定,因为它们被用于触发条件:The result of the LOCK TABLES statement is that t1 and t2 are locked because they appear in the statement, and t3 and t4 are locked because they are used within the trigger:

  • t1 根据 WRITE写入。t1 is locked for writing per the WRITE lock request.

  • t2 被锁定用于写入,尽管请求是针对 READ 锁。这是因为 t2入触发器中,因此 READ 请求被转换为 WRITE 请求。t2 is locked for writing, even though the request is for a READ lock. This occurs because t2 is inserted into within the trigger, so the READ request is converted to a WRITE request.

  • t3 被锁定用于读取,因为它只在触发器内部读取。t3 is locked for reading because it is only read from within the trigger.

  • t4 被锁定写入,因为它可能在触发器内被更新。t4 is locked for writing because it might be updated within the trigger.

Table-Locking 限制与条件Table-Locking Restrictions and Conditions

你可以安全地使用 KILL“来终止等待表锁的会话。参见 第 15.7.8.4 节,”KILL Statement“。You can safely use KILL to terminate a session that is waiting for a table lock. See Section 15.7.8.4, “KILL Statement”.

LOCK TABLES 和 UNLOCK TABLES 不能在存储程序中使用。LOCK TABLES and UNLOCK TABLES cannot be used within stored programs.

performance_schema不能被锁定为 LOCK TABLES,除了 setup_xxx 表。Tables in the performance_schema database cannot be locked with LOCK TABLES, except the setup_xxx tables.

由 LOCK TABLES是一个 MySQL 服务器。它与 NDB Cluster 不兼容,后者无法在多个实例中强制执行 SQL 级别锁mysqld。你可以在 API 应用中强制锁定。更多信息请参见 第 25.2.7.10 节,“关于多个 NDB 集群节点的限制”。The scope of a lock generated by LOCK TABLES is a single MySQL server. It is not compatible with NDB Cluster, which has no way of enforcing an SQL-level lock across multiple instances of mysqld. You can enforce locking in an API application instead. See Section 25.2.7.10, “Limitations Relating to Multiple NDB Cluster Nodes”, for more information.

以下语句在 LOCK TABLES 语句生效时被禁止: CREATE TABLE CREATE TABLE ... LIKECREATE VIEW, DROP VIEW,以及存储函数、过程和事件的 DDL 语句。The following statements are prohibited while a LOCK TABLES statement is in effect: CREATE TABLE, CREATE TABLE ... LIKE, CREATE VIEW, DROP VIEW, and DDL statements on stored functions and procedures and events.

对于某些操作,必须访问 mysql。例如,HELP 语句需要服务器端帮助表的内容,CONVERT_TZ() 可能需要读取时区表。服务器会隐式锁定系统表以便必要时读取,这样你就不必显式锁定它们。这些表的处理方式如下:For some operations, system tables in the mysql database must be accessed. For example, the HELP statement requires the contents of the server-side help tables, and CONVERT_TZ() might need to read the time zone tables. The server implicitly locks the system tables for reading as necessary so that you need not lock them explicitly. These tables are treated as just described:

mysql.help_category
mysql.help_keyword
mysql.help_relation
mysql.help_topic
mysql.time_zone
mysql.time_zone_leap_second
mysql.time_zone_name
mysql.time_zone_transition
mysql.time_zone_transition_type

如果你想在这些表上显式地放置一个WRITE并且LOCK TABLES 语句,必须是唯一被锁定的表;不能用相同的语句锁定其他表。If you want to explicitly place a WRITE lock on any of those tables with a LOCK TABLES statement, the table must be the only one locked; no other table can be locked with the same statement.

通常,你不需要锁定表,因为所有单一的 UPDATE语句都是原子性的;没有其他会话可以干扰当前执行的任何 SQL 语句。不过,在某些情况下,锁定表可能带来优势:Normally, you do not need to lock tables, because all single UPDATE statements are atomic; no other session can interfere with any other currently executing SQL statement. However, there are a few cases when locking tables may provide an advantage:

  • 如果你将对一组MyISAM表格,锁定你要使用的表会快得多。锁定MyISAM表格会加快插入、更新或删除操作,因为 MySQL 在调用UNLOCK TABLES之前不会刷新锁定表的键缓存。通常,键缓存会在每条 SQL 语句后刷新。If you are going to run many operations on a set of MyISAM tables, it is much faster to lock the tables you are going to use. Locking MyISAM tables speeds up inserting, updating, or deleting on them because MySQL does not flush the key cache for the locked tables until UNLOCK TABLES is called. Normally, the key cache is flushed after each SQL statement.

    锁定表格的缺点是没有会话可以更新READ被锁定的表(包括持有锁的那个会话),也没有会话可以访问WRITE除了持有锁的那个会话之外的被锁定表。The downside to locking the tables is that no session can update a READ-locked table (including the one holding the lock) and no session can access a WRITE-locked table other than the one holding the lock.

  • 如果你在非事务存储引擎中使用表,必须使用 LOCK TABLES,这样你必须使用 SELECT 和 an UPDATE。这里展示的示例需要LOCK TABLES 才能安全执行:If you are using tables for a nontransactional storage engine, you must use LOCK TABLES if you want to ensure that no other session modifies the tables between a SELECT and an UPDATE. The example shown here requires LOCK TABLES to execute safely:

    LOCK TABLES trans READ, customer WRITE;
    SELECT SUM(value) FROM trans WHERE customer_id=some_id;
    UPDATE customer
      SET total_value=sum_from_previous_statement
      WHERE customer_id=some_id;
    UNLOCK TABLES;
    

    如果没有 LOCK TABLES,有可能有其他会话在 执行 之间插入 transthe SELECT 和 UPDATE 语句。Without LOCK TABLES, it is possible that another session might insert a new row in the trans table between execution of the SELECT and UPDATE statements.

在许多情况下,你可以通过使用相对更新(LOCK TABLES)或UPDATE customer SET value=value+new_value函数来避免使用LAST_INSERT_ID() function.You can avoid using LOCK TABLES in many cases by using relative updates (UPDATE customer SET value=value+new_value) or the LAST_INSERT_ID() function.

你还可以通过使用用户级的咨询锁函数GET_LOCK()和 RELEASE_LOCK()。这些锁保存在服务器的哈希表中,并以 pthread_mutex_lock() 和 pthread_mutex_unlock() 实现以实现高速。参见 第 14.14 节“锁定函数”。You can also avoid locking tables in some cases by using the user-level advisory lock functions GET_LOCK() and RELEASE_LOCK(). These locks are saved in a hash table in the server and implemented with pthread_mutex_lock() and pthread_mutex_unlock() for high speed. See Section 14.14, “Locking Functions”.

有关锁策略的更多信息,请参见 第 10.11.1 节“内部锁定方法”。See Section 10.11.1, “Internal Locking Methods”, for more information on locking policy.