When users are signing up to our service, I want to allocate one solr core (the kind of resource) out of many. One core exclusively for one user (for example!). And I want to use select ...for update
to ensure that concurrent signups see (and use) different rows.
Stuff works for the first signup transaction; we get the row we are allowed to use. But for the second (onward), Lock wait timeout exceeded
happens; when I wanted the next row.
Why is MySQL giving throwing this error?
From terminal 1:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from SolrCoresPreallocated order by id limit 1 for update;
+----+-------------+-----+-----+
| id | used_status | sid | cid |
+----+-------------+-----+-----+
| 1 | 0 | 0 | 400 |
+----+-------------+-----+-----+
1 row in set (0.00 sec)
In terminal 2:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from SolrCoresPreallocated order by id limit 1 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
I actually wanted to see:
mysql> select * from SolrCoresPreallocated order by id limit 1 for update;
+----+-------------+-----+-----+
| id | used_status | sid | cid |
+----+-------------+-----+-----+
| 2 | 0 | 0 | 401 |
+----+-------------+-----+-----+
1 row in set (0.00 sec)
My data is:
mysql> select * from SolrCoresPreallocated;
+----+-------------+-----+-----+
| id | used_status | sid | cid |
+----+-------------+-----+-----+
| 1 | 0 | 0 | 400 |
| 2 | 0 | 0 | 401 |
| 3 | 0 | 0 | 402 |
| 4 | 0 | 0 | 403 |
| 5 | 0 | 0 | 404 |
| 6 | 0 | 0 | 405 |
+----+-------------+-----+-----+
6 rows in set (0.00 sec)
I described my problem in: Different transactions must guarantedly select different items; avoid contentions