Registration lock

Asked

Viewed 2,330 times

5

How could I lockar a record in Mysql?

For example, I have a record that is being accessed by the user 000, and I want to lock this record so that users other than 000 cannot access it. That is possible?

2 answers

3


First you need to ensure the following two prerequisites for the registry lock to work:

  1. The storage engine of your table must be configured to Innodb.
  2. Your record lock query must be executed after starting a transaction.

You can run registry lock in Mysql in two ways:

1) SELECT ... FOR UPDATE

Any lock concluding with the command FOR UPDATE will not allow other transactions to read, update or delete the record. Other transactions may read these records only after the first transaction is completed (commited) or canceled (roll back).

Example:

; Esta consulta não irá permitir que outras transações leiam o registro com id=10;
; Ela também não irá permitir atualizações ou exclusões di registro.
SELECT * FROM NomeDaTabela WHERE id=10 FOR UPDATE

2) LOCK IN SHARED MODE

Any lock with the command LOCK IN SHARED MODE will allow other transactions to read the blocked record but will not allow other transactions to update or delete the record. Other transactions may update or delete the record when the first transaction is completed or cancelled.

Example:

; Esta consulta não irá permitir que outras transações atualizem ou excluam o registro de id=10.
; Ela permite que outras transações leiam o registro de id=10.
SELECT * FROM NomeDaTabela WHERE id=10 LOCK IN SHARE MODE;

This response was adapted from the article in English "Row Locking With Mysql", available in http://www.xpertdeveloper.com/2011/11/row-locking-with-mysql/

  • Cool, what I need to know now, is how to give Unlock on the record, because I need that when a record is opened, it stays locked for 5 min.

  • +Rafael, those 5 minutes you speak is the maximum time the record should be locked, or every time you make a lock you want it to last exactly 5 minutes?

  • When I make the lock, it should last exactly 5 minutes

  • I believe that the lock only allows to define the maximum timeout, but not minimum. The solution would then have to be at application level, not at database level. For example, for each access to the table, your application stores the user who is accessing and the time of access, and for each new access to that table the system then validates if it is another user. If it’s another user, it checks if it’s past five minutes since the first user logged in. If another user accesses and has already passed the five minutes, the system then records this new user and the new lock time.

  • Table? or table record?

  • To the table records, for each of them.

  • At this link, it seems that it is possible to do the database level, changing the timeout, take a look: https://dev.mysql.com/doc/innodb/1.1/en/innodb-other-changes-innodb_lock_wait_timeout.html

  • @Vynstus I took a look, and it says "The length of time a transaction Waits for a Resource, before Giving up and rolling back the statement, is determined by the value of the Configuration Parameter innodb_lock_wait_timeout". That time is what the transaction will wait until it is completed or that gives timeout for not having managed to be completed within the expected time. But it doesn’t keep the transaction open for N minutes. Another thing: keep the transaction open for N minutes lock all tables, making the system unavailable, which is unviable for any application.

  • @The documentation in English is available at http://downloads.mysql.com/docs/refman-4.1-pt.a4.pdf, and this variable innodb_lock_wait_timeout is described in page 474, section 7.5.3. Innodb Startup Options, if you might be interested.

  • Got it. One question, the lock of the Innodb engine is the line level, in which case it is not possible to lock an entire innodb table? using LOCK TABLE?

Show 5 more comments

1

This process is known as Deadlock.

Check out the Mysql documentation, I hope this link helps you as well as other people:

https://dev.mysql.com/doc/refman/5.5/en/innodb-lock-modes.html

A shared lock (S) allows the transaction that holds the lock to read a record.

A unique lock (X) allows the transaction that keeps the lock from updating or deleting a line.

Example:

This example involves two clients, client A and client B.

Client A creates the table containing a record and starts the transaction by selecting this row, follows:

mysql> CREATE TABLE t (i INT) ENGINE = InnoDB;
Query OK, 0 rows affected (1.07 sec)

mysql> INSERT INTO t (i) VALUES(1);
Query OK, 1 row affected (0.09 sec)

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE;
+------+
| i    |
+------+
|    1 |
+------+
1 row in set (0.10 sec)

Then client B starts the transaction and executes a delete on this line:

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

mysql> DELETE FROM t WHERE i = 1;

Upshot:

mysql> DELETE FROM t WHERE i = 1;
ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transaction

This example was taken from the Mysql site, I did not detail the whole process, but you can refer to the link I provided.

I hope it helps you as much as it helped me to learn something new.

  • Cool!! And for me to finalize the transaction I just give a COMMIT? IE, to give Unlock in the record.

  • As it is in the example I believe you do not need to give COMMIT, Mysql will execute the COMMIT when it reaches the last SQL command in an instruction. And as soon as the client A ends with a COMMIT the record will be unlocked for client B for example.

  • Last SQL command? I don’t understand...

  • For example, you insert a line and NOT from COMMIT, and then you give a SELECT, these two commands only, the last command will be SELECT and right below Mysql takes care of giving the COMMIT;

  • How will he know that select is my last SQL statement? I could insert more instructions like Count max etc

Browser other questions tagged

You are not signed in. Login or sign up in order to post.