メニューを閉じる

テクノモバイルグループ

メニューを開く

2018.05.30

DB

MySQL8で、排他ロックされたレコードがスキップできるようになった。

こんにちは、MTです。
今回は、MySQL8で SKIP LOKEDNOWAIT の2機能が追加されたので、実際に試してみました。

どちらも行ロックに関する機能で、

  • SKIP LOCKED
    • ロック対象のレコードが既にロックされている場合はスキップする。
  • NOWAIT
    • ロック対象のレコードが既にロックされている場合は、直ちに失敗にする。

というものです。
他のDBには同等の機能が備わっていたりするのですが、MySQLはやっと提供されたかという感じです。

従来(MySQL5.7まで)は上記のような機能は提供されていなかったので、

  • 既にロックされていた場合は、ロック待ちタイムアウトまで待ち続ける

  • ロック用のカラムで頑張る

方法を取るしかありませんでした。

 

ロックされていた場合は直ちにエラーを返してきてほしいものですが、そのような機能は無いので待ち続けるしかありません。
また、ロックを判断するためのカラムに関しては、MySQLの仕組みにテーブル構造が引きずられてるので、できるだけ避けたい。
今回追加された SKIP LOCKED、NOWAIT は、上記の問題を解決します。

準備

まずはデータの準備から。
IDと名前だけの user テーブルを作成し、データを登録します。

SKIP LOCKED – ロックされているレコードはスキップする

あるレコードを排他ロックする際、既にロックされている場合にはスキップする機能です。
例えば トランザクションAid1 のレコードをロックし、トランザクションB で全レコードをロックしようとした場合、
トランザクションA でロックした id1 のレコードは トランザクションB でスキップされます。

id1 のレコードは抽出されていませんね。

NOWAIT – ロックされている場合は直ちにエラーにする

SKIP LOCKED は既にロックされていた場合にロックしない(スキップする)機能でしたが、NOWAIT はロックできないと分かった時点で直ちに失敗にするための機能です。
少し話を戻しますが、SELECT FOR UPDATE SKIP LOCKED の結果が「対象レコード無し」の場合、

「レコード自体が存在しない」のか「他でロックされている」のか

が分かりません。

業務要件上、上記のようなケースが許容されている場合は良いですが「処理対象データのロックが取れない」場合にはエラーに倒したい場合が多いのではないでしょうか。
かつ、ロックが取れないと判明した時点で即時に。
このような場合は NOWAIT を使用します。

文章だと分かりませんが、SELECT文を発行した直後にエラーが返ってきます。

まとめ

  • MySQL8で、ロックの制御に関する機能が追加された。
  • ロック済みレコードをスキップしたい場合には SKIP LOCKED
  • ロック済みの場合に直ちにエラーにしたい場合は NOWAIT

【テクノモバイルではエンジニア/デザイナーを積極採用中です!】

下記項目に1つでも当てはまる方は是非、詳細ページへ!
  • 自分でアプリを作ってみたい
  • ITで世の中にワクワクを生み出したい
  • 使いやすさ、デザインにこだわったWebサイトを開発したい

採用情報の詳細はこちら


Qangaroo(カンガルー)

  • 徹底した見やすさと優れた操作性で、テストの「見える化」を実現。
  • テストの進捗が見える。開発がスマートに進む。
  • クラウド型テスト管理ツール『Qangaroo(カンガルー)』
https://qangaroo.jp/

最近の記事

SNS共有

X CLOSE
X CLOSE
X CLOSE