プロバイダ:VC-NET スクリプト:Perl

在庫管理などで、在庫を変更中に変更前の値を第三者が閲覧してしまうと矛盾がおきますよね?そこで質問なのですがこの様な場合みなさんどうされてるのですか?


私は、書き換えるファイルを

file → file986172208

アクセスした時間(Perlのtime)を付加してファイルロックをして、
書き込みを終えれば

file986172208 → file

また元に戻す。


イントラネット上では期待した結果が得られたのですが、いざアップしたら
”サーバー側のエラーですよ”と表示されました。
ですがTELNETから動作させるとうまく動作しました。
ファイルのパーミションは

スクリプトファイル:755 データファイル:666 です。

みなさんからのご意見お待ちしています。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

まず、イントラネット上で動作したというのは、どういうふうに実


行させたら動作したという意味でしょうか?それは、ローカルな
WEBサーバー経由の cgi として動作したのか、telnet で動作させ
たのと同レベルなのかですが。

あと、どういうエラーが起きたのかは、わからないのでしょうか?
スクリプトの各段階で、どこまで進んだか、どういう状況かを、適
当なファイルにログとして残して行って、解析した方がいいと思い
ます。そのファイルさえ作成されないのであれば、スクリプトの起
動もできてないのかもしれませんし。

それから、ロックの方法としては、ファイル名の rename で行って
いるということですね?rename に失敗したら、ロック失敗という
方式でしょうか?原理的には正しくロックできる方法だと思います。

# もっとも、時刻を付加しなくても、共通のファイル名を使っても
# 大丈夫なはずです。もしそれでだめだとすると、時刻を付加して
# も1秒以内に複数のアクセスがあると破綻しますから。

ただ、何かの原因で更新中に file という名前のファイルが作成さ
れないことと、更新中にそのスクリプトが死なないことが保証でき
なければいけません。前者が起きると多重のアクセスが生じますし、
後者が起きるとデッドロックになります。

unix のサーバーで perl を使い、そのサーバー内のプロセス同士
でロックするのなら、flock を使うのが確実だと思います。
man perlfunc で flock の項目に使用例もあるので、見てください。

この回答への補足

さっそくのご回答ありがとうございます m(_ _)m

イントラネット上で動作したというのは、ローカルでWEBサーバーをたてて、
そこからCGI経由で動作したということです。
サーバー:httpd 1.27c(フリーウェア)

それから初歩的なことなのですがエラーログは自分で取れるものなのですか?
サーバー側が作ってくれるものだとばっかりおもってました。
だとしたらどのようにすればいいのでしょうか?(次から次へと質問が…)

flockはファイルをオープンしたりライトする際に有効なんですよね?
データをユーザーが入力してる間はずーーとロック状態でないとまずいんですよ。

”いま100個あったのに発注かけたら0個だと!?どうなってるんだ”とか…


ロック方法は、ファイル名の rename で行っています!
参考:http://www.din.or.jp/~ohzaki/perl.htm#File_Lock

今回が初めての投稿なので、何分的確に質問できていませんがもう少しお付き合いください。宜しくお願い致します。

補足日時:2001/04/06 12:16
    • good
    • 0

パーミッションについて:



httpd の設定にもよりますが、~daresore にある cgi を実行した
場合には、daresore の権限にするのが普通ですから、本人が読み
書きできるなら cgi プログラムにもできると考えてもいいかと思
います。でないと、自分のディレクトリのファイルが他人の cgi
プログラムからアクセスできることになります。もっとも、それが
確かかどうかは、ログをちゃんと調べる必要があります。

ログについて:

適当なログファイルを
open(STDERR, ">/tmp/logfile");
のようにオープンして、自分で
print STDERR ...;
していけばいいだけのことです。ログを作るにもパーミッションの
問題がからむと面倒なので、/tmp か /var/tmp の使用が許されて
いるなら、とりあえずはそこに作るのがいいでしょう。どういう権
限で動いているかは、そのログファイルのオーナーが自分かどうか
で調べられます。

で、目的のファイルが rename に失敗したり、open できなかった
ら、
die "$!"; か warn "$!";
しておきましょう。

ロックの方法について:

一般論として、長時間ロックをするのはよくありません。
「いま100個あったのに発注かけたら0個だと!?どうなってるんだ」
の問題は、顧客が発注するのが遅かったせいにすればいいのです。
でないと、100個あったことは確認したけど、発注せずにいきなり
接続を切ったりしてしまったらどうなりますか?cgi プロセスがそ
のことに気付いて、ファイル名を戻すまでは、他の顧客は100個あ
ることすら確認できなくなりますよ。
    • good
    • 0
この回答へのお礼

返事が送れて申し訳ございません。
エラーログの作成うまくいきました!これからはこのようなエラーは
ログから探っていきます。お忙しいところ本当にありがとうございました。
また今度はデッドロックしても定期的にチェックするプログラムなんかも作成したいですね。これからも何卒宜しくお願いします。^^

お礼日時:2001/04/06 16:45

ファイル名のrenameを行うには、当該ファイルのあるディレクトリに対して書き込みを許可するPermissionが立っていないといけません。


今回の場合、sub_dirのPermissionが701になっているということですが、この場合nobodyはsub_dirに対する書き込み許可が与えられていませんので、renameに失敗しInternal Server Errorが出ていると思われます。

従って、sub_dirのPermissionを777にすれば予定通りの動作をすると思いますが。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。m(_ _)m
サーバーのエラーが英語なのでついついめをそらしていましたが正しく”Internal Server Error”でした。

ちょっとしたスクリプトを書くときにCGI&Perlのポケットリファレンスを
読むのですが、記述されてました!!

”ファイルシステムを超えてファイル名を変更しようとすると通常失敗に終わります(プラットフォームに依存)。”

以前イントラネットで使用したOSはwindowsだったので意識してませんでしたがそれを意味していたなんて…。パーミション属性に書き込み許可があるのは分かっていましたがディレクトリにも同じことが言えるなんてホント新発見です(私だけ?)rename もまた然り、名前を 書・き・換・え・る ですね!

いやー、普段は過去ログをみてるだけでしたが投稿することでたった一日で解決するなんて。回答をしていただいたみなさんに感謝の気持ちでいっぱいです。

お礼日時:2001/04/06 17:02

ディレクトリのパーミッションがおかしいのでは?



補足
通常 *普通*の環境であれば、CGIの実行は、ログインアカウントではなく
nobadyなどの専用のユーザーで実行されます。

それではちゃんとしたロックはかけられないと思いますが
それは質問じゃないんですよね?

この回答への補足

またまた回答いただきありがとうございます。(^v^)
ご指摘を受けたディレクトリのパーミッションなのですが


public_html(ルートのディレクトリ):701
   |
   sub_dir(サブディレクトリ):701
     |
     file(変更したいファイル):666

                       です。

windowsユーザーにはパーミションたる概念がまったくないので、
ピンとこないのです、はい。

”ログインアカウントではなくnobadyなどの専用のユーザーで実行されます。 ”
”それではちゃんとしたロックはかけられない”

う~ん、難しいですね。ブラウザからアクセスすることが”nobadyなどの専用のユーザー”でアクセスしているということですかね?
変更するファイルのパーミッションを 666 で権限を与えてるとおもうのですが?

勉強になるHPなどありましたらご紹介ください。たびたびお手数をお掛けしますが宜しくお願い致します。

補足日時:2001/04/06 12:56
    • good
    • 0

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


このカテゴリの人気Q&Aランキング