WEBアプリのDB更新

WEBアプリがデータベースを更新するまでのパターン。

  1. 入力画面で情報を入力する。
  2. 確認画面で更新する情報を確認する。
  3. データベースを更新して、更新完了画面を表示する。

確認画面でデータベースにロックをかけて、データベースを更新するなんてことができると思えないから(できない…と思うけど)、毎画面、毎画面で少なくとも更新前には、データベースの情報が別スレッド、別プロセスに更新されていないかチェックが必要になると思う。


よくやるチェック方法は確認画面で更新対象のレコードの更新日時を取得して、データベースを更新する場合に、更新するレコードと突き合わせてみる。突き合せ方は以下の2通りぐらいかな。

  1. 更新日時をキーとして、データベースを検索。レコードがあれば更新、無ければNG。
  2. 更新日時をキーとして、データベースを更新。更新件数が1件以上ならばOK、0件ならばNG。

個人的には、チェックと実際の更新処理が1つのSQLですむ後者の方が好き。前者で、チェックするときに「SELECT FOR UPDATE」でロックをかけてもよいと思う。後者の方法ならDELETEでも使えそう。

INSERTの場合はどうするだろう…

INSERTの場合は、確認画面でユニークなIDを発行して、データベースの更新時にそのIDをINSERTする。同じ、IDが存在しなければOKだし、もしあれば…一意制約に引っかかるな。
SQLExceptionを補足して、エラー処理をしてもいいけど、できればSQLExceptionはフレームワーク側に処理させたい。
そうすると…

  1. (チェック)IDをキーにして、データベースを検索。
  2. (チェック)レコードがあればNG。
  3. (更新)INSERTする。

…この方法だと、チェックと更新にタイムラグがあるのがいやだ。1つのSQLで済ます方法か、チェックするときにレコードにロック(まだ存在していないレコードにロック?)する方法を考えてみよう…*1

*1:ふと思ったけど、設計によってはメソッド単位でロック(というかsynchronizedで同期)できるかも