2016-03-19 3 views
1

次の問題にいくつかのアドバイスを提供してください: 私はユニークなコードのリストを持っています。コードは一度だけ使用する必要があります。そのため、各コードに関連付けられたステータス(使用/未使用)があります。SQL - ロックするかロックしない:次の未使用コードを選択

複数のスレッドが次の未使用コードを取得しようとすると、競合/競合状態が心配です。

SQLデータベース(私の場合はMySQL)を使用して実装する最良の方法は何ですか?

最初のオプション分離レベルロックを使用し、読み取りコミットすることである:スレッドの競合の場合

start transaction in read-committed isolation level 
select code from code_table where status = 'not-used' for update 
update code_table set status = 'used' where code = :code 
commit transaction 

、Iは、「データベース・スレッドは」ロックされた行につまずくであろうと考えています行書き込みロックが解放されない限り待機し、このコードレコードがすでに使用されていることを(読み取りコミットされた分離レベルのために)表示し、他のコードレコードに移動します。

start transaction in default isolation level (read-repeatable) 
select code from code_table where status = 'not-used' 
commit transaction 

start transaction in default isolation level (read-repeatable) 
update code_table set status = 'used' where code = :code 
commit transaction 

Javaコードでは、私がどれだけチェックします:

番目のオプションは(私たちは休止状態を使用していない)楽観的ロックを休止状態に類似したものを使用することで、ここでの手順の説明がありますレコードが更新されました。レコードが1つ更新されている場合は、レコードが更新されていればすべてOKです.3回目(または5回目)の試行後にステップを繰り返します。例外をスローします。

ご迷惑をおかけして申し訳ございません。 ありがとうございます

+0

OK、削除されたSQL Server .... – user3489820

答えて

2

第2のオプション - 楽観的なロック - はかなり悪い考えです。ウィキペディア
https://en.wikipedia.org/wiki/Optimistic_concurrency_control

オプティミスティック並行性制御(OCC)。 。 。 。 。 。 。
。 。 。 。 。 。 。 。一般に、データ競合の少ない環境で で使用されます。競合が稀である場合、 のトランザクションはロックを管理する費用なしで完了することができ、 のトランザクションは他のトランザクションのロックを にロックするのを待たずにクリアされ、他の並行性制御のメソッドより高いスループットをもたらします。 しかし、データリソースの競合が頻発する場合は、トランザクションを繰り返し再開するコストが であり、パフォーマンスが犠牲になる。 ;これらの条件で他の同時実行制御 メソッドの方がパフォーマンスが良いと一般的に考えられています。ただし、ロックを使用すると、デッドロックを回避しても同時ロックを大幅に制限することができるので、 ロックベースの(「悲観的」)メソッドでもパフォーマンスが低下する可能性があります。

私は簡単にX並行スレッドで次のシナリオを想像することができます:

  • スレッド#1は、次の未使用のレコードを取得します#1スレッド#2は、次の未使用のレコードを取得します
  • #1
  • スレッド#3次の未使用のレコード#1
  • スレッド#4グラムを取得しますETS次の未使用のレコード#1
    .....
    .....
  • スレッド#1は、レコード#1を更新し、その後、#2
  • スレッド#利用可能な次のレコードを取ります2 衝突レコード#1を更新しようとしたとき、そうリトライを検出し、次の利用可能なレコードにかかる#2スレッド#3 は、衝突を検出
  • ようリトライ、レコード#1を更新しようとしているときと#2
  • スレッド#4 は、レコード#1を更新しようとしたとき、衝突を検出するようにリトライと次を取り、次の利用可能なレコードを取り利用可能なレコード#2 .....
    .....
    .....
    など...などです。多くの競合と再試行。

あなたは最初のオプションに固執する必要があります。
競合を減らすには、トランザクションをできるだけ短くしたい場合があります。

+0

ありがとうございます!最初のオプションを実装しましたが、誰かに確認させるのは良いことです。 – user3489820

関連する問題