Mysql:当查询这个sql时:“select * from user limit 0,1000”,如果允许删除操作

时间:2012-09-04 04:21:48

标签: mysql locking

我有一个mysql锁定问题: 如果我查询这个sql:select * from user order by id asc limit 0,1000。 然后另一个线程同时删除用户表中0,1000之间的行,如果允许的话?

1 个答案:

答案 0 :(得分:0)

MySQL Documentation for InnoDB中,它指出InnoDB does locking on the row level and runs queries as nonlocking consistent reads by default

更直接的是,Internal Locking Methods,即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

还有:Any way to select without causing locking in MySQL?