0

ユーザーが私たちのサービスにサインアップするとき、多くの中から 1 つの solr コア (一種のリソース) を割り当てたいと考えています。1 人のユーザー専用の 1つのコア(たとえば!)。そして、同時サインアップが異なる行select ...for updateを確認 (および使用) するようにするために使用したいと考えています。

Stuff は最初のサインアップ トランザクションで機能します。使用できる行を取得します。しかし、2 番目 (以降) では、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 に答える