今回は、データ更新処理内に排他制御を加えてみたので、そのサンプルプログラムを共有する。
排他制御は、1つのデータに複数のアクセスが見込まれる場合に、データ不整合が起こらないようにするために用いられる。更新前にデータ取得する際にロックをかける「悲観的排他制御」が、開発現場でよく使われる。そのため、今回は「悲観的排他制御」を利用したサンプルプログラムを作成してみた。
排他制御についての詳細は、以下のサイトを参照のこと。
https://qiita.com/NagaokaKenichi/items/73040df85b7bd4e9ecfc
なお、今回のサンプルプログラムは長くなるため、前提条件と完成したサンプルプログラムの画面イメージのみ記載し、ソースコードの内容は次回の記事で記載する。
前提条件
下記記事の実装が完了していること。
完成した画面イメージの共有
ここでは、以下の3パターンについて、完成した画面イメージの共有を行う。
すぐに悲観ロックを取得できた場合
通常の、すぐに悲観ロックを取得できた場合の動作は以下の通り。
1) Spring Bootアプリケーションを起動し、「http:// (ホスト名):(ポート番号)」とアクセスした場合の初期表示は以下の通りなので、ID=2の「更新」リンクを押下
2) 以下のように入力画面が表示されるので、内容を変更し「確認」ボタンを押下
3) 以下のように確認画面が表示されるので、「送信」ボタンを押下すると、5秒以内に悲観ロックが取得できた場合のみ、10秒間待機する仕組みになっている
悲観ロックの取得に失敗した場合
悲観ロックの取得に失敗した場合の動作は以下の通り。なお、確認画面が表示されるまでは、すぐに悲観ロックを取得できた場合と同じ動作となる。
2) SQL Developer上で、直ちに悲観ロックを取得する下記SQLを実行
1 | select * from USER_DATA where ID = 2 for update nowait |
なお、select文に「for update」を付与することで、悲観ロックによるデータ取得が実行できる。また、「nowait」を付与することで、悲観ロックが取得できなかった場合はすぐにエラーにすることができる。
4) 5秒以内に悲観ロックが取得できなかったので、下記エラーページに遷移
なお、画面の方では、select文に「for update wait 5」を付与し、5秒間だけ待機しても悲観ロックが取得できなかった場合はエラーになるようにしている。
また、悲観ロックを解除するには、commit文またはrollback文を実行すればよいので、SQL Developer上でcommit文またはrollback文を実行すれば、「すぐに悲観ロックを取得できた場合」と同じ動作となる。
最初は悲観ロックを取得できなかったものの、5秒以内に取得できた場合
最初は悲観ロックを取得できなかったものの、5秒以内に取得できた場合の動作は以下の通り。なお、確認画面が表示されるまでは、すぐに悲観ロックを取得できた場合と同じ動作となる。
2) SQL Developer上で、直ちに悲観ロックを取得する下記SQLを実行
1 | select * from USER_DATA where ID = 2 for update nowait |
4) 5秒以内に、SQL Developer上でrollback文を実行
これで、悲観ロックが解除され、画面上での、5秒以内に悲観ロックが取得できた場合のみ、10秒間待機する仕組みが実行される。