- PR -

WEBアプリでのデータベースのロック

投稿者投稿内容
七味唐辛子
ぬし
会議室デビュー日: 2001/12/25
投稿数: 660
投稿日時: 2004-02-04 10:37
WEBアプリでのデータベースのロックの方法にテーブルのカラムにタイムスタンプを
書き込んで、ごにょごにょすると聞きましたが、これはどのようなアプローチなのでしょうか
ロックというよりは、値の整合性をとるための方法かもしれませんが教えてください。
axis
会議室デビュー日: 2003/10/30
投稿数: 9
投稿日時: 2004-02-04 11:03
axisです。
JavaでなくColdFusionでWEBアプリの開発をしていますが、よく以下のようなやり方をしています。

レコードのレイアウトが
・field1:値1
・field2:値2
・lastupdate:最終更新タイムスタンプ
とします。

1.レコードを読み込み画面に内容を表示する。
lastupdateのタイムスタンプをセッション変数に保持する。

2.内容を変更し、送信ボタンを押す。

3.変更した内容の確認画面を表示する。

4.送信ボタンを押す。

5.「1」で読み込んだレコードを再度読み込み、読み込んだlastupdateとセッション変数に保持したlastupdateを比較する。
違っていたらエラーメッセージを表示する。
同じならDBに変更をかける。lastupdateは現在のタイムスタンプで更新する。

実際は「3」の時点でもタイムスタンプの比較をしています。

説明が下手で申し訳ないのですが、こんな感じでやっています。
たるたる
会議室デビュー日: 2003/09/29
投稿数: 16
投稿日時: 2004-02-04 12:02
JavaのWEBアプリ開発ですがaxisさんと同じ方法をとっています。
ひとつ加えるとすると、

5番のトランザクション処理中で
引用:
「1」で読み込んだレコードを再度読み込み


の時にレコードロックしています。
七味唐辛子
ぬし
会議室デビュー日: 2001/12/25
投稿数: 660
投稿日時: 2004-02-04 13:18
axisさんありがとうございます


たるたるさんありがとうございます

ところでたるたるさんの手法で

>の時にレコードロックしています。
とのことですがなぜレコードロックするのでしょうか?
coasm
大ベテラン
会議室デビュー日: 2001/11/26
投稿数: 237
投稿日時: 2004-02-04 13:21
ほとんど同じ原理ですが、最終更新時刻の替わりに
「レコード更新の毎にカウントアップするカウンタ」を使う方法もあります。

webアプリなら反応時間が充分長いので大丈夫でしょうが、
RMIで通信するクライアントサーバシステムで最終更新時刻方式の管理をして、
同一時刻(ミリ秒単位)内に2回以上更新をかけられると競合を検知できないのが
問題になったことがありました。
そういう意味では、カウントアップ方式のほうが安全です
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2004-02-04 13:30
楽観的排他制御というやつですね。
Webでは、DBのデータを表示したあとずっとロックをかけているわけにはいきませんので(ブラウザを閉じられちゃうかもしれないから)、更新時に、表示するためにデータを取得したときと値が変わっていないか調べて、変わっていないなら更新をするという方法を取ります。

Yahooで検索してみたらこんなドキュメントがありました。
http://www.simosimo.info/know/oracle/exctrl.pdf

このドキュメントでは更新日時ではなく実際のデータを比べたり、coasmさんのおっしゃるような変更番号(カウンタ)の話が載っていました。
おばけ
ぬし
会議室デビュー日: 2002/11/14
投稿数: 609
お住まい・勤務地: 東京都江東区
投稿日時: 2004-02-04 13:36
引用:

とのことですがなぜレコードロックするのでしょうか?


axisさんの「2004-02-04 11:03」の書き込みを詳しく解説すると、

5.
5-1. 「1」で読み込んだレコードを再度読み込み、読み込んだlastupdateとセッション変数に保持したlastupdateを比較する。
5-2-1. 違っていたらエラーメッセージを表示する。
5-2-2. 同じならDBに変更をかける。lastupdateは現在のタイムスタンプで更新する。

となるわけですが、5-1.で一度DBにSELECTを発行し、その後Javaのロジックで比較を
実行し、更に5-2-2.で今度はDBにUPDATEを発行するわけですが、内容上この二つの
操作は1つのトランザクションで行われなければなりません。したがって、5-1.で
SELECTを発行した際に「行レベル更新ロック」をかけて当該レコードをロックしておき、
5-2-2.のUPDATEで更新及びトランザクションのコミットを行います。

こうしないと、5-1.で比較して、「あ、一緒だから更新しよう」と5-2-2.に行くまでの
間に、誰かが当該レコードを更新してしまうかもしれません。

説明になってますでしょうか?
axis
会議室デビュー日: 2003/10/30
投稿数: 9
投稿日時: 2004-02-04 13:54
>たるたるさん、おばけさん
私のつたない説明のフォローありがとうございます。
ほんと説明下手ですいません。
私もロジック上ではこのようになっています。

>coasmさん、一郎さん
カウンタを使う方法もあったのですね。
タイムスタンプを使うと思い込んで他の方法は考えつきませでした。
勉強になります。

スキルアップ/キャリアアップ(JOB@IT)