13.3.6 LOCK TABLES and UNLOCK TABLES StatementsLOCK TABLES语句和UNLOCK TABLES语句

LOCK TABLES
tbl_name [[AS] alias] lock_type
    [, tbl_name [[AS] alias] lock_type] ...
lock_type: {
    READ [LOCAL]
  | [LOW_PRIORITY] WRITE
}

UNLOCK TABLES

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. MySQL使客户端会话能够显式地获取表锁,以便与其他会话协作访问表,或者在会话需要独占访问表时防止其他会话修改表。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 explicitly acquires table locks for the current client session. LOCK TABLES显式获取当前客户端会话的表锁。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权限和SELECT权限。

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. 对于视图锁定,LOCK TABLES将视图中使用的所有基表添加到要锁定的表集中,并自动锁定它们。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检查视图定义器(对于SQL SECURITY DEFINER视图)或调用器(对于所有视图)是否对这些表具有适当的权限。

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显式锁定表,则触发器中使用的任何表也将被隐式锁定,如锁表和触发器中所述。

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

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

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. UNLOCK TABLES的另一个用途是释放使用FLUSH TABLES WITH READ LOCK语句获取的全局读锁,这使您能够锁定所有数据库中的所有表。See Section 13.7.8.3, “FLUSH Statement”. 请参阅第13.7.8.3节,“FLUSH语句”(This is a very convenient way to get backups if you have a file system such as Veritas that can take snapshots in time.)(如果您的文件系统(如Veritas)可以及时拍摄快照,那么这是一种非常方便的备份方式。)

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. 持有WRITE锁的会话可以执行表级操作,如DROP TABLETRUNCATE TABLEFor sessions holding a READ lock, DROP TABLE and TRUNCATE TABLE operations are not permitted.对于持有READ锁的会话,不允许执行DROP TABLETRUNCATE TABLE操作。

The following discussion applies only to non-TEMPORARY tables. 以下讨论仅适用于非临时表。LOCK TABLES is permitted (but ignored) for a TEMPORARY table. 对于临时表,允许(但忽略)LOCK TABLESThe 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表锁获取

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

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

READ [LOCAL] lock:

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

  • 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.其他会话可以在不显式获取READ锁的情况下读取表。

  • The LOCAL modifier enables nonconflicting INSERT statements (concurrent inserts) by other sessions to execute while the lock is held. LOCAL修饰符允许其他会话在持有锁时执行非冲突的INSERT语句(并发插入)。(See Section 8.11.3, “Concurrent Inserts”.) (请参阅第8.11.3节,“并发插入”。)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. 但是,如果要在持有锁的同时使用服务器外部的进程操作数据库,则不能使用READ LOCALFor InnoDB tables, READ LOCAL is the same as READ.对于InnoDB表,READ LOCALREAD相同。

[LOW_PRIORITY] 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.在释放锁之前,其他会话无法访问它。

  • Lock requests for the table by other sessions block while the WRITE lock is held.保持WRITE锁定时,其他会话对表的锁定请求将被阻止。

  • The LOW_PRIORITY modifier has no effect. LOW_PRIORITY修饰符无效。In previous versions of MySQL, it affected locking behavior, but this is no longer true. 在以前的MySQL版本中,它影响了锁定行为,但现在不再如此。It is now deprecated and its use produces a warning. 它现在已被弃用,使用它会产生警告。Use WRITE without LOW_PRIORITY instead.改用无LOW_PRIORITYWRITE

WRITE locks normally have higher priority than READ locks to ensure that updates are processed as soon as possible. WRITE锁通常比READ锁具有更高的优先级,以确保尽快处理更新。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. 这意味着,如果一个会话获得READ锁,然后另一个会话请求WRITE锁,则后续的READ锁请求将等待,直到请求WRITE锁的会话获得并释放锁。(An exception to this policy can occur for small values of the max_write_lock_count system variable; see Section 8.11.4, “Metadata Locking”.)(对于max_write_lock_count系统变量的较小值,可能会出现此策略的例外情况;请参阅第8.11.4节,“元数据锁定”。)

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语句必须等待,那么它将阻塞,直到可以获取所有锁为止。

A session that requires locks must acquire all the locks that it needs in a single LOCK TABLES statement. 需要锁的会话必须在单个LOCK TABLES语句中获取它所需的所有锁。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:例如,在以下语句序列中,尝试访问t2时出错,因为t2未在LOCK TABLES语句中锁定:

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

Tables in the INFORMATION_SCHEMA database are an exception. INFORMATION_SCHEMA数据库中的表是一个例外。They can be accessed without being locked explicitly even while a session holds table locks obtained with LOCK TABLES.即使会话持有使用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;

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

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.会话可以显式释放其锁,也可以在某些条件下隐式释放锁。

  • A session can release its locks explicitly with UNLOCK TABLES.会话可以使用UNLOCK TABLES显式释放其锁。

  • If a session issues a LOCK TABLES statement to acquire a lock while already holding locks, its existing locks are released implicitly before the new locks are granted.如果会话在已经持有锁的情况下发出LOCK TABLES语句以获取锁,则在授予新锁之前,会隐式释放其现有锁。

  • If a session begins a transaction (for example, with START TRANSACTION), an implicit UNLOCK TABLES is performed, which causes existing locks to be released. 如果会话开始事务(例如,使用START TRANSACTION),将执行隐式UNLOCK TABLES,从而释放现有锁。(For additional information about the interaction between table locking and transactions, see Interaction of Table Locking and Transactions.)(有关表锁定和事务之间交互的其他信息,请参阅表锁定和事务的交互。)

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注意

If you use ALTER TABLE on a locked table, it may become unlocked. 如果在锁定的表上使用ALTER TABLE,它可能会被解锁。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. 例如,如果尝试第二个ALTER TABLE操作,结果可能是错误Table 'tbl_name' was not locked with LOCK TABLESTo handle this, lock the table again prior to the second alteration. 要处理此问题,请在第二次修改之前再次锁定表。See also Section B.3.6.1, “Problems with ALTER TABLE”.另见第B.3.6.1节,“ALTER TABLE的问题”

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

LOCK TABLES and UNLOCK TABLES interact with the use of transactions as follows:LOCK TABLESUNLOCK TABLES与事务的使用进行交互,如下所示:

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

  • UNLOCK TABLES implicitly commits any active transaction, but only if LOCK TABLES has been used to acquire table locks. UNLOCK TABLES隐式提交任何活动事务,但仅当LOCK TABLES用于获取表锁时。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:例如,在以下语句集中,UNLOCK TABLES释放全局读锁,但不提交事务,因为没有有效的表锁:

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

  • 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. FLUSH TABLES WITH READ LOCK获得全局读锁而不是表锁,因此在表锁定和隐式提交方面,它与LOCK TABLESUNLOCK TABLES的行为不同。For example, START TRANSACTION does not release the global read lock. 例如,START TRANSACTION不会释放全局读取锁。See Section 13.7.8.3, “FLUSH Statement”.请参阅第13.7.8.3节,“FLUSH语句”

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

  • 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. LOCK TABLESUNLOCK TABLES与事务表(如InnoDB表)一起使用的正确方法是使用SET autocommit = 0(而不是START TRANSACTION)开始事务,后跟LOCK TABLES,并且在显式提交事务之前不调用解锁表。For example, if you need to write to table t1 and read from table t2, you can do this:例如,如果需要写入表t1并从表t2读取,可以执行以下操作:

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

    When you call LOCK TABLES, InnoDB internally takes its own table lock, and MySQL takes its own table lock. 当您调用LOCK TABLES时,InnoDB在内部拥有自己的表锁,MySQL拥有自己的表锁。InnoDB releases its internal table lock at the next commit, but for MySQL to release its table lock, you have to call UNLOCK TABLES. InnoDB在下一次提交时释放其内部表锁,但MySQL要释放其表锁,必须调用UNLOCK TABLESYou 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. 您不应具有autocommit=1,因为在调用锁表之后,InnoDB会立即释放其内部表锁,死锁很容易发生。InnoDB does not acquire the internal table lock at all if autocommit = 1, to help old applications avoid unnecessary deadlocks.如果autocommit=1InnoDB根本不会获取内部表锁,以帮助旧应用程序避免不必要的死锁。

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

LOCK TABLES and Triggers锁定表和触发器

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.这些锁与使用LOCK TABLES语句显式获取的锁的时间相同。

  • 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.如果是这样,读锁就足够了。否则,将使用写锁。

  • 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. 如果使用LOCK TABLES显式锁定表以进行读取,但由于可能在触发器中对其进行修改而需要锁定以进行写入,则将使用写锁而不是读锁。(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.)(也就是说,由于表在触发器中的外观而需要的隐式写锁会导致表的显式读锁请求转换为写锁请求。)

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

LOCK TABLES t1 WRITE, t2 READ;

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

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;

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:LOCK TABLES语句的结果是t1t2被锁定,因为它们出现在语句中,t3t4被锁定,因为它们在触发器中使用:

  • t1 is locked for writing per the WRITE lock request.根据WRITE锁请求,t1被锁定以进行写入。

  • t2 is locked for writing, even though the request is for a READ lock. t2在写入时被锁定,即使请求是READ锁定。This occurs because t2 is inserted into within the trigger, so the READ request is converted to a WRITE request.之所以会发生这种情况,是因为t2插入到触发器中,所以READ请求被转换为WRITE请求。

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

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

Table-Locking Restrictions and Conditions表锁定限制和条件

You can safely use KILL to terminate a session that is waiting for a table lock. 您可以安全地使用KILL终止正在等待表锁的会话。See Section 13.7.8.4, “KILL Statement”.请参阅第13.7.8.4节,“KILL语句”

LOCK TABLES and UNLOCK TABLES cannot be used within stored programs.LOCK TABLESUNLOCK TABLES不能用在存储程序内部。

Tables in the performance_schema database cannot be locked with LOCK TABLES, except the setup_xxx tables.除了setup_xxx表外,performance_schema数据库中的表不能用锁表锁定。

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.LOCK TABLES语句生效时,禁止在存储函数、过程和事件上使用以下语句:CREATE TABLECREATE TABLE ... LIKECREATE VIEWDROP VIEW和DDL语句。

For some operations, system tables in the mysql database must be accessed. 对于某些操作,必须访问mysql数据库中的系统表。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. 例如,HELP语句需要服务器端帮助表的内容,CONVERT_TZ()可能需要读取时区表。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

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.如果要使用LOCK TABLES语句在这些表中的任何一个上显式地放置WRITE锁,则该表必须是唯一被锁定的表;不能使用同一语句锁定其他表。

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. 通常,您不需要锁定表,因为所有单个UPDATE语句都是原子的;任何其他会话都不能干扰任何其他当前正在执行的SQL语句。However, there are a few cases when locking tables may provide an advantage:但是,在一些情况下,锁定表可能提供优势:

  • 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. 如果要在一组MyISAM表上运行许多操作,那么锁定要使用的表要快得多。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. 锁定MyISAM表会加快插入、更新或删除这些表的速度,因为在调用UNLOCK tables之前,MySQL不会刷新锁定表的密钥缓存。Normally, the key cache is flushed after each SQL statement.通常,在每个SQL语句之后都会刷新密钥缓存。

    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.锁定表的缺点是,没有会话可以更新READ锁定表(包括持有锁的表),也没有会话可以访问持有锁的表以外的WRITE锁定表。

  • 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. 如果要为非事务存储引擎使用表,如果要确保在SELECTUPDATE之间没有其他会话修改表,则必须使用LOCK TABLESThe example shown here requires LOCK TABLES to execute safely:此处显示的示例要求LOCK TABLES以安全执行:

    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;

    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,另一个会话可能会在SELECTUPDATE语句执行之间在trans表中插入新行。

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.在许多情况下,通过使用相对更新(UPDATE customer SET value=value+new_valueLAST_INSERT_ID()函数,可以避免使用LOCK TABLES

You can also avoid locking tables in some cases by using the user-level advisory lock functions GET_LOCK() and RELEASE_LOCK(). 在某些情况下,您还可以通过使用用户级建议锁定函数GET_lock()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. 这些锁保存在服务器的哈希表中,并使用pthread_mutex_lock()pthread_mutex_unlock()实现,以实现高速。See Section 12.15, “Locking Functions”.请参阅第12.15节,“锁定函数”

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