这不是完整/正确的MySQL查询伪代码:
Select * from Notifications as n where n.date > (CurrentDate-10 days) limit by 1 FOR UPDATE
http://dev.mysql.com/doc/refman/5.0/en/select.html指出:如果将FOR UPDATE与使用页面或行锁的存储引擎一起使用,则查询所检查的行将被写锁,直到当前交易结束
是这里只有被MySQL锁定返回的一条记录还是必须扫描以查找单个记录的所有记录?
我们为什么不尝试一下呢?
设置数据库
CREATE DATABASE so1; USE so1; CREATE TABLE notification (`id` BIGINT(20), `date` DATE, `text` TEXT) ENGINE=InnoDB; INSERT INTO notification(id, `date`, `text`) values (1, '2011-05-01', 'Notification 1'); INSERT INTO notification(id, `date`, `text`) values (2, '2011-05-02', 'Notification 2'); INSERT INTO notification(id, `date`, `text`) values (3, '2011-05-03', 'Notification 3'); INSERT INTO notification(id, `date`, `text`) values (4, '2011-05-04', 'Notification 4'); INSERT INTO notification(id, `date`, `text`) values (5, '2011-05-05', 'Notification 5');
现在,启动两个数据库连接
连接1
BEGIN; SELECT * FROM notification WHERE `date` >= '2011-05-03' FOR UPDATE;
连接2
BEGIN;
如果MySQL锁定所有行,则以下语句将阻塞。如果仅锁定返回的行,则不应阻塞。
SELECT * FROM notification WHERE `date` = '2011-05-02' FOR UPDATE;
确实的确会阻止。
有趣的是,我们也无法添加将要读取的记录,即
INSERT INTO notification(id, `date`, `text`) values (6, '2011-05-06', 'Notification 6');
块呢!
我现在不能确定MySQL是否只是在锁定一定百分比的行时继续执行并锁定整个表,或者在确保SELECT ... FORUPDATE查询结果永远不会被其他事务更改的情况下真正明智的做法是(用INSERT,UPDATE或DELETE),而锁被保持。
SELECT ... FORUPDATE
INSERT
UPDATE
DELETE