試してみませんか?
データベースを設定する
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');
次に、2つのデータベース接続を開始します
接続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 ... FOR UPDATE
クエリを別のトランザクションで変更することはできません(INSERT
を使用) 、UPDATE
、またはDELETE
)ロックが保持されている間。