我有一个 mysql 锁定问题:如果我查询这个 sql: select * from user order by id asc limit 0,1000
。然后另一个线程同时删除用户表中0,1000之间的行,如果允许的话?
1 回答
在InnoDB 的 MySQL 文档中,它指出InnoDB does locking on the row level and runs queries as nonlocking consistent reads by default
。
然而,更直接的是内部锁定方法,它说MySQL uses table-level locking for MyISAM, MEMORY, and MERGE tables, allowing only one session to update those tables at a time
. 另外,这个:
MySQL grants table write locks as follows:
1. If there are no locks on the table, put a write lock on it.
2. Otherwise, put the lock request in the write lock queue.
MySQL grants table read locks as follows:
1. If there are no write locks on the table, put a read lock on it.
2. Otherwise, put the lock request in the read lock queue.
好的,让我们来消化一下:在 InnoDB中,每一行都有自己的锁,这意味着您的查询将遍历表,直到它遇到有锁的行。但是,在 MyISAM中,整个表只有一个锁,它是在执行查询之前设置的。
换句话说,对于 InnoDB,如果 DELETE 操作在 SELECT 操作读取该行之前删除了该行,那么该行将不会显示在结果中。但是,如果 SELECT 操作首先读取该行,那么它将在结果集中返回,但任何未来的 SELECT 操作都不会显示该行。如果您想有意锁定 InnoDB 中的整个结果集,请查看SELECT ... FOR UPDATE。
在 MyISAM 中,表默认是锁定的,因此取决于哪个查询先开始执行:如果 DELETE 操作先开始,则不会使用 SELECT 返回该行。但是如果 SELECT 操作首先开始执行,那么该行确实会被返回。
这里有更多关于交错的信息:http: //dev.mysql.com/doc/refman/5.0/en/select.html