Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UPDATE with SELECT, will it lock each row or all SELECTed records

It is unclear to me (by reading MySQL docs) if the following query ran on INNODB tables on MySQL 5.1, would create WRITE LOCK for each of the rows the db updates internally (5000 in total) or LOCK all the rows in the batch. As the database has really heavy load, this is very important.

UPDATE `records`
INNER JOIN (
  SELECT id, name FROM related LIMIT 0, 5000
) AS `j` ON `j`.`id` = `records`.`id` 
SET `name` = `j`.`name`

I'd expect it to be per row but as I do not know a way to make sure it is so, I decided to ask someone with deeper knowledge. If this is not the case and the db would LOCK all the rows in the set, I'd be thankful if you give me explanation why.

like image 366
ddinchev Avatar asked Jun 11 '13 20:06

ddinchev


People also ask

Does SELECT for update lock row?

The SELECT FOR UPDATE statement is used to order transactions by controlling concurrent access to one or more rows of a table. It works by locking the rows returned by a selection query, such that other transactions trying to access those rows are forced to wait for the transaction that locked the rows to finish.

Does SELECT lock row?

A SELECT in SQL Server will place a shared lock on a table row - and a second SELECT would also require a shared lock, and those are compatible with one another.

Does SELECT for update block SELECT?

SELECT FOR UPDATE is a SQL command that's useful in the context of transactional workloads. It allows you to “lock” the rows returned by a SELECT query until the entire transaction that query is part of has been committed.

Does MySQL lock a row for update?

FOR UPDATE : Any lock placed with the `FOR UPDATE` will not allow other transactions to read, update or delete the row. Other transaction can read this rows only once first transaction get commit or rollback.


1 Answers

The UPDATE is running in transaction - it's an atomic operation, which means that if one of the rows fails (because of unique constrain for example) it won't update any of the 5000 rows. This is one of the ACID properties of a transactional database.

Because of this the UPDATE hold a lock on all of the rows for the entire transaction. Otherwise another transaction can further update the value of a row, based on it's current value (let's say update records set value = value * '2'). This statement should produce different result depending if the first transaction commits or rollbacks. Because of this it should wait for the first transaction to complete all 5000 updates.

If you want to release the locks, just do the update in (smaller) batches.

P.S. autocommit controls if each statement is issued in own transaction, but does not effect the execution of a single query

like image 59
Maxim Krizhanovsky Avatar answered Sep 24 '22 08:09

Maxim Krizhanovsky