0

当用户注册我们的服务时,我想从许多中分配一个 solr 核心(资源的种类)。一个核心供一位用户使用(例如!)。而且我想用来select ...for update确保并发注册看到(和使用)不同的行

东西适用于第一次注册交易;我们得到允许使用的行。但是对于第二个(向前),Lock wait timeout exceeded发生了;当我想要下一行时

为什么 MySQL 会抛出这个错误?

从 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)

在 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)

其实我想看看:

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)

我的数据是:

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)

我在中描述了我的问题:不同的交易必须保证选择不同的项目;避免争吵

4

1 回答 1

1

这个查询实际上总是请求并锁定同一行,无论哪个 MySQL 连接运行它。

select * from SolrCoresPreallocated order by id limit 1 for update;

锁定的行不会以某种方式神奇地从未来的查询中排除。他们只是被锁定了。这就是你看到的问题;您的所有操作都锁定了同一行。

如果你能做这样的事情(注意:伪代码;注意:我不理解你的模式)它很可能会工作得更好

 begin;

 update SolrCoresPreallocated
    set allocated = (this customer id)
  where allocated = 0 
  limit 1;

(check result; if no rows were modified you ran out of allocated=0 rows.)

select * from SolrCoresPreallocated where allocated = (this customer id);

commit;
于 2012-10-05T12:19:22.230 回答