我有一个mysql锁问题:
如果我查询此 sql:select * from user order by id asc limit 0,1000
。
然后另一个线程同时删除用户表中0,1000之间的行,如果允许的话?
最佳答案
在MySQL Documentation for InnoDB ,它指出 InnoDB 在行级别上锁定并且默认情况下将查询作为非锁定一致读取运行
。
然而,更直接的是Internal Locking Methods ,其中表示 MySQL 对 MyISAM、MEMORY 和 MERGE 表使用表级锁定,一次只允许一个 session 更新这些表
。另外,这个:
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 操作首先读取该行,那么它会在结果集中返回,但任何 future 的 SELECT 操作都不会显示该行。如果您想有意锁定 InnoDB 中的整个结果集,请查看 SELECT ... FOR UPDATE .
在 MyISAM 中,表默认是锁定的,所以这取决于哪个查询开始执行:如果 DELETE 操作先开始,那么 SELECT 将不会返回该行。但是如果 SELECT 操作首先开始执行,那么该行确实会被返回。
这里有更多关于隔行扫描的信息:http://dev.mysql.com/doc/refman/5.0/en/select.html
关于Mysql:查询这条sql :"select * from user limit 0,1000"时,是否允许删除操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12256765/