MySQL InnoDB lock row - mysql

I work with mySQL InnoDB Table.
Mysql database queries with php script.
When A user select a record in specific table I'd like to lock this and allow only read process for other user.
So I try to use
SELECT * FROM parent WHERE NAME = 'Jones' LOCK IN SHARE MODE;
So my question is when user B try to select the same record how to know that the record is locked and when user A try to update record how to authorize this operation.
Thanks for helping

InnoDB row locks are only intended for temporary use during a transaction (e.g, when you want to temporarily hold up anyone else who's trying to look at or modify the row). If you want to allow users of your application to "lock" records, row locking isn't suited for this purpose. Instead, do it at the application level: create a column in the table to represent which of your users has locked the record.

Related

Is there any disadvantage of rowlock mechanism in mysql?

I am beginner to mysql but little basics are cleared but I have some doubt about locking system of mysql. Row lock mechanism is provided by InnoDB engine in mysql and it improves table performance as compared to table lock.
But my Question is little different, For 1st trasanction,
update table employee set userName = 'Kraven' from employee where userName='raj'
now , I guess it will lock row where userName = raj So,
If I want to retrieve data employees having userName starting with R or r, will it give me 1 row less which is locked, Or will it hold lock because my locked row is part of query for other transaction?
If I am searching for userName which are starting with K, will it escape rowlock of first transaction and miss the update caused by first transaction?
Correct me if I am wrong, i just want to clear idea of rowlock.

Lock an entire single table but still allow to access other tables in the same session on MySQL

Is it possible to lock a single table on MySQL for a session and still be able to read and write on other unlocked tables on the same session that locked that table while the table is still locked?
Yes, LOCK TABLES does exactly this.

Access database by many users simultaneously

If a database is access by many users then it is necessary to take lock on database? If YES then how to take lock on table or database? What is problem if not taking a lock?
For Example: If a user update table and some one fetch data from this table then it is necessary to take lock on this table?
You should use Transactions:
When the user updates the table, the UPDATE statement should be inside START TRANSACTION clause. If the UPDATE succeeds, then COMMIT else ROLLBACK.
You can lock tables with LOCK TABLES. However, if you lock tables with LOCK TABLES, all updates stall until integrity checks are made. If you obtain a READ LOCAL lock (as opposed to a write lock) for a table that enables concurrent inserts at the end of the table, reads are permitted, as are inserts by other clients.
http://dev.mysql.com/doc/refman/5.5/en/commit.html
http://dev.mysql.com/doc/refman/5.0/en/ansi-diff-transactions.html
Depending on your transaction isolation level MySQL will automatically issue locks. How they interact is determined by the transaction isolation level.
Only in very specific situations will you manually request locks on a table or database resource. Most of the time this is done by MySQL for you. The above answers has links which will be very important to read and understand.

MySQL InnoDB Transactions + Locking

MySQL Verion: v5.0.95
Basically I have clients trying to get data - each client should only get unique rows.
START TRANSACTION;
SELECT id where result='new';
UPDATE SET result='old' WHERE id=$id;
COMMIT;
LOCK IN SHARED MODE on the select statement still lets other clients read the data, which seems like a problem.
Basically I need the data selected once, updated, and not read again by another client.
SELECT FOR UPDATE will block another read, while LOCK IN SHARED MODE will allow the read, but won't allow update from another client

Row lock for update status

I have a table of "commands to do" with a status ('toprocess', 'processing', 'done')
I have several instances (amazon ec2) with a daemon asking for "commands to do".
The daemon asks for rows with status 'toprocess', then it processes, and at the end of each loop it changes the status to 'done'.
The thing is that, before starting that loop, I need to change all rows 'toprocess' to status 'processing', so other instances will not take the same rows, avoiding conflict.
I've read about innodb row locks, but I don't understand them very well ...
SELECT * from commands where status = 'toprocess'
then I need to take the ID's of these results, and update status to 'processing' , locking these rows until they are updated.
How can i do it ?
Thank you
You'd use a transaction , and read the data with FOR UPDATE, which will block other selects that include the FOR UPDATE on the rows that gets selected
begin transaction;
select * from commands where status = 'toprocess' for update;
for each row in the result:
add the data to an array/list for processing later.
update commands set status='processing' where id = row.id;
commit;
process all the data
Read a bit about the FOR UPDATE , and InnoDB isolation levels.
A possible (yet not very elegant) solution may be to first UPDATE the record, then read its data:
Each deamon will have a unique ID, and the table will have a new column named 'owner' for that ID.
Then the deamon will run something like "UPDATE table SET status='processing', owner='theDeamonId' where status='toprocess' ... LIMIT 1"
While the update runs the row is locked, so no other deamon can read it.
After the update this row is Owned by a specific deamon, then it can run a SELECT to fetch all necessary data from that row (WHERE status='processing' AND owner= 'theDeamonId').
Finally, the last UPDATE will set the row to 'processed', and may (or may not) remove the owner field. Keeping it there will also enable some statistics about the deamons' work.
As far as I know you can't use MySQL to lock a row (using a built-in method). You have two options though:
If your table should not be read by any other process until the locks are released then you can use table level locking as described here
You can implement your own basic row locking by updating a value in each row you're processing, and then have all your other daemons checking whether this property is set (a BIT data type would suffice).
InnoDB locks at a row level for reading and updating anyway, but if you want to lock the rows for an arbitrary period then you may have to go with the second option.