This is not a full/correct MySQL query only pseudo-code:
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 states: If you use FOR UPDATE with a storage engine that uses page or row locks, rows examined by the query are write-locked until the end of the current transaction
Is here only the one record returned locked by MySQL or all records it has to scan to find the single record?
From mysql official doc: A locking read, an UPDATE, or a DELETE generally set record locks on every index record that is scanned in the processing of the SQL statement. It does not matter whether there are WHERE conditions in the statement that would exclude the row.
A SELECT ... FOR UPDATE reads the latest available data, setting exclusive locks on each row it reads. Thus, it sets the same locks a searched SQL UPDATE would set on the rows.
MySQL Locks: Write LocksIt is the session that holds the lock of a table and can read and write data both from the table. It is the only session that accesses the table by holding a lock. And all other sessions cannot access the data of the table until the WRITE lock is released.
An UPDATE lock is a read lock which means "I intend to update this row/page/table". Readers are not blocked by this lock, but only one process can hold an UPDATE lock on a resource. please simulate a scenario which show where update lock play a key role because we know sql server place a lock when update data.
Why don't we just try it?
Set up the database
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');
Now, start two database connections
Connection 1
BEGIN; SELECT * FROM notification WHERE `date` >= '2011-05-03' FOR UPDATE;
Connection 2
BEGIN;
If MySQL locks all rows, the following statement would block. If it only locks the rows it returns, it shouldn't block.
SELECT * FROM notification WHERE `date` = '2011-05-02' FOR UPDATE;
And indeed it does block.
Interestingly, we also cannot add records that would be read, i.e.
INSERT INTO notification(id, `date`, `text`) values (6, '2011-05-06', 'Notification 6');
blocks as well!
I can't be sure at this point whether MySQL just goes ahead and locks the entire table when a certain percentage of rows are locked, or where it's actually really intelligent in making sure the result of the SELECT ... FOR UPDATE
query can never be changed by another transaction (with an INSERT
, UPDATE
, or DELETE
) while the lock is being held.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With