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