アプリ版:「スタンプのみでお礼する」機能のリリースについて

初めまして。
まだ初心者の身なのですが質問させてもらいます。

サーブレット・jspでJDBCを使いデータベースとの処理を行って簡単なショッピングサイトのようなものを作っています。

まずsetAutocomit() = falseでトランザクションを開始し
データベースのUPDATEを行って、最後に確定する場合comit
キャンセルする場合rollbackとしています。

しかし1人のユーザーがトランザクションを行っている場合に他のユーザーからアクセスされた場合にデータベースのトランザクション中の値を取ってきたいのですが、どうしてもトランザクションでUPDATEされる前の値になってしまうのです。

これを防止するのが排他制御というものだというのは分かったのですが
実際のやり方については、結構調べたのですがあまり載っていませんでした。

データベースはMySQLを使っています。
よろしければJDBCでの排他制御についてのアドバイス、もしくは詳しく説明されているサイトなどございましたら是非教えてください。
よろしくお願いします。

A 回答 (3件)

仰るような用途ですとACID特性に反するため、トランザクション以外で考える必要があるように思います。


ですが実現するのはかなり難しい気がします。
例えば、ユーザ1がロールバックする前にユーザ2がコミットした場合はどうなるか等、何らかの矛盾が発生するはずです。
    • good
    • 0

Postgresの詳しい中身はわからないですが、普通のRDBMSはレコード単位のロックを行ってトランザクションを隔離しているはずです。


ですので、同じ行に対して2つのトランザクションが更新しようとした場合、後で更新しようとした方のトランザクションが待つことになります。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

ということは先ほどの例は行えないのですか?
しかし1人のトランザクションが終わるまで他のユーザーがUPDATEできないとなると少し効率の悪いシステムになりますね。
トランザクション以外の方法も考えてみたいと思います。

お礼日時:2006/10/17 22:57

質問させていただきたいのですが、試された手順は以下のようなタイミングでしょうか。


1.ユーザ1がトランザクション開始
2.ユーザ2がトランザクション開始
3.ユーザ1がUPDATE
4.ユーザ1がCOMMIT
5.ユーザ2がSELECT

MySQL等の一般的なRDBMSでは、排他レベルというものが設定できますが、一番厳しいものにすると、ユーザ2がSELECTして取得できるデータはユーザ2がトランザクションを開始した段階のデータとなります。
ユーザ2がSELECTして取得できるデータをユーザ1がCOMMITしたデータとしたい場合は、排他レベルを下げる必要があります。
MySQLにおける排他レベルの設定方法は参考URLを参照下さい。

また、排他レベルの詳しい説明はPostgreSQLのドキュメントがお勧めです。
http://www.postgresql.jp/document/pg732doc/user/ …

これで解決できると思いますが、本当に確実な排他制御をしたい場合は、テーブルロックを試されてみてはいかがでしょうか。パフォーマンスが格段に落ちるのでお勧めできませんが…。
http://dev.mysql.com/doc/refman/4.1/ja/lock-tabl …

参考URL:http://dev.mysql.com/doc/refman/4.1/ja/innodb-tr …

この回答への補足

例えば最初のデータベースの値が1としますと
1.ユーザ1がトランザクション開始
2.ユーザ2がトランザクション開始
3.ユーザ1がUPDATE 1→3 +2を行う
4.ユーザ2がSELECT 3
5.ユーザ2がUPDATE 3→6 +3を行う
6.ユーザ1がSELECT 6
7.ユーザ1がROLLBACK 6→4 +2を取り消し
8.ユーザ2がSELECT 4
となるようにしたいのです。

排他レベルについて勉強したのですが
一番低いUNCOMMITTEDに設定しても
上の例で5の位置でロックがかかってしまいUPDATEできなくなってしますのです。
URLについてはありがとうございました。
色々調べてみます。

補足日時:2006/10/16 21:35
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!