Starting from MySQL 4.0.20, and 4.1.2, InnoDB honors LOCK TABLES; MySQL does not return from LOCK TABLE .. WRITE until all other threads have released all their locks to the table. In MySQL 4.0.19 and before, InnoDB ignored table locks, which allowed one to more easily simulate transactions with a combination of MyISAM and InnoDB tables. The default value is 1, which means that LOCK TABLES causes also InnoDB internally to take a table lock. In applications using AUTOCOMMIT=1, InnoDB's internal table locks can cause deadlocks. You can set innodb_table_locks=0 in my.cnf to remove that problem. This option is not
available in MySQL 5.0.
LOCK TABLES sets table locks, but it is the higher MySQL layer above the InnoDB layer that sets these locks. Beginning with MySQL 4.0.20 and 4.1.2, InnoDB is aware of table locks if innodb_table_locks=1 and AUTOCOMMIT=0, and the MySQL layer above InnoDB knows about row-level locks. Otherwise, InooDB's automatic deadlock detection cannot detect deadlocks where such table locks are involved. Also, since the higher MySQL layer does not know about row-level locks, it is possible to get a table lock on a table where another user currently has row-level locks. However, this does not endager transaction integrity, as discussed in Section 15.11.10, “Deadlock Detection and Rollback”. See also Section 15.17, “Restrictions onInnoDB Tables”.
A new startup option named innodb_table_locks was added that causes LOCK TABLE to
also acquire InnoDB table locks. This option is enabled by default. This can cause deadlocks in applications that use AUTOCOMMIT=1 and LOCK TABLES. If you application encounters deadlocks after upgrading, you may need to add innodb_table_locks=0 to your my.cnf file.
Beginning with MySQL 4.0.20 and 4.1.2, InnoDB is aware of table locks if innodb_
table_locks=1 (1 is the default), and the MySQL layer above it knows about row-level locks. Otherwise, InnoDB cannot detect deadlocks where a table lock set by a MySQL LOCK TABLES statement or a lock set by a storage engine other than InnoDB is involved. You must resolve these situations by setting the value of the innodb_lock_wait_timeout system variable.
Before MySQL 4.0.20 or 4.1.2, the MySQL LOCK TABLES operation does not know about
InnoDB row-level locks set by completed SQL statements. This means that you can get a table
lock on a table even if there still exist transactions by other users who have row level locks on
the same table. Thus your operations on the table may have to wait if they collide with these
locks of other users. Also a deadlock is possible. However, this does not endanger transaction integrity,
because the row level locks set by InnoDB always take care of the integrity. Also, a table
lock prevents other transactions from acquiring more row level locks (in a conflicting lock
mode) on the table.
Beginning with MySQL 4.0.20 and 4.1.2, the MySQL LOCK TABLES operation acquires two
locks on each table if innodb_table_locks=1. (1 is the default.) In addition to a table lock
on the MySQL layer, it also acquires an InnoDB table lock. Older versions of MySQL do not
acquire InnoDB table locks. Beginning with MySQL 4.0.22 and 4.1.7, the old behavior can be
selected by setting innodb_table_locks=0. If no InnoDB table lock is acquired, LOCK
TABLES completes even if some records of the tables are being locked by other transactions.
All InnoDB locks held by a transaction are released when the transaction is committed or aborted.
Thus, it does not make much sense to invoke LOCK TABLES on InnoDB tables in AUTOCOMMIT=
1 mode, because the acquired InnoDB table locks would be released immediately.
• Sometimes it would be useful to lock further tables in the course of a transaction. Unfortunately,
LOCK TABLES in MySQL performs an implicit COMMIT and UNLOCK TABLES. An InnoDB
variant of LOCK TABLES has been planned that can be executed in the middle of a transaction.
1. 从mysql4.0.20和4.1.2开始,Innodb开始支持innodb_table_locks(default 1)lock tables
lock table...write会等待所有其他线程释放表上的锁
2. innodb_table_locks缺省值为1, 意味着Innodb内部可以获得表锁
3. 如果autocommit=1,Innodb的内部表锁可能会导致deadlock
可以通过设置innodb_table_locks=0来解决这个问题
4. 这个参数从mysql5.0开始不再使用,明显是个过渡方案
5. 如果4.1.2-5.0之间版本设置innodb_table_locks=0,如果由于lock tables语句或者其它存储引擎设置了lock导致dead lock,Innodb将不能自动侦测到. 这时,必须设置innodb_lock_wait_timeout变量,使deadlock超时后rollback
Innodb事务回滚相关的信息如下:
When InnoDB performs a complete rollback of a transaction, all the locks of the transaction are released. However, if just a single SQL statement is rolled back as a result of an error, some of the locks set by the SQL statement may be preserved. This is because InnoDB stores row locks in a format such it cannot know afterward which lock was set by which SQL statement.
如果正常回滚,事务加的锁全部释放;否则如果回滚语句出错,导致只有事务中的部分语句被回滚掉,那有可能部分lock没有释放.因为Innodb不知道是哪条sql语句加的row lock
如果在mysql5.0以下,4.1.2以上版本发生莫名其妙的死锁问题,建议检查一下应用程序中是不是启动了autocommit=1(session的缺省设置)