|
no prev page |
1/1ページ(1件) |
no next page |
|
|
|
まともなデータベースを触っていないあたしが言うのも何ですが・・・
最近は、新しく取ったレンタルサーバーで、SQLをいじり始めました。
これは、ここのページをまるごと移動し、もうちょっと楽に管理しようというのが目的で、いまdbmopenで行っていることをdbiを使ってMysqlで行うのです。
それって、大して違わなくないですか?とか言われそうですがDBMSを利用することの利点というのはあるのです。
そもそもdbmはハッシュファイルでありデータベースではないw
検索機能がないので、キーとなる物を全て管理保存する必要がある。
それ以外にも機能が少ない。
ただ・・・ハッシュ構造であるが故の利点、データの読み書きは勝手にしてくれるだけの存在なのです。
まぁ、そっちは良いのです。
そんな訳でまともなDBMSであるサーバーにデータを写したかったんですが、これがこれでなかなかうまくいかない。
色々と調べている内に、当該サーバーのMySQLの現在の設定ではトランザクションを管理していないのです。
トランザクションって何ですか?的な人が、現在の世の中では多いみたいですが??
トランザクションは、処理の単位です。
仕事と言っても良いです。
作業を開始して、作業を終了して結果を返す
ここまでがトランザクションです。
ホームページに限らず、あらゆる物は、作業のバッティング(衝突)が起こる可能性があります。
ここは、訪問者が少ないですがw
大手のホームページとかは、見に来る人が1秒間に数千人とか言う規模で居ます。
こんなに沢山の人が見に来ていても、ホームページは随時更新され、新しい情報が次々と公開されていくのです。
でも、実際問題、新しい項目を書き込み中は、データが一部不定になるために正常に読むことが出来なくなるんです。
たとえば、新しい記事を追加するとき、
記事本文を追加する、記事が追加されたことを記録する
と二つの作業が必要になるかもしれません。
場合によっては、書き込んだ人、書き込んだ日付、更新情報の管理など、諸々の作業が沢山必要かもしれません。
この作業が全部正常に完了しないと、新しい記事を読むことが出来ないだけでなく、従来の記事も正常に表示できないかもしれません。
なので、記事の更新中は、他の人が読めないようにしなくてはいけないのです。
これが、トランザクションを処理で重要な、排他制御という物です。
記事の更新中、他のユーザーが見ないようにするだけでなく、他の人が同時に更新することもないようにしなくてはいけません。
しかしMySQLはこの機能が標準でOFFなだけではなく!
ない方が良い的なスタンスらしいのです。
それはそれで困りますね〜
となると、自分で排他制御し無くてはいけません。
さすがに、selectの実行中に他から更新されることはありませんが・・・
select分と他の何かの間に誰かが割り込んで処理をする可能性はあります。
重要なのは2つ、
・更新作業中はだれも閲覧が出来ないようにすること
・同時に更新が出来ないようにすること
「更新作業中はだれも閲覧が出来ないようにすること」
1つめ
更新中は、DB(でなくてもかまいませんが?)にフラグをセットして、フラグが無くなるまで閲覧は待たせる。
2つめ
タイミング悪く、既に閲覧中の場合
フラグのチェックタイミングが微妙で閲覧を開始してしまった場合
これは、閲覧側のチェックを冗長化させることで可能になります。
まず、基本的なチェックとして、更新フラグの有り無しを確認します。
閲覧用のフラグを、インクリメント(+1)します。
もう一度更新フラグの確認をします。このとき、更新フラグがあった場合は−1して、待機します。
これで、更新中は必ず待機します。
じゃぁ、更新プログラム側はどうしましょうか?
更新フラグを立てることで、それ以降後から入ってくる閲覧者は居ません。
既に閲覧中の人はどうでしょうか?閲覧者は、閲覧フラグを+1するのでこれが0になるのを待てば、閲覧者は居なくなります。
微妙なタイミングで入ってきた人はどうかと言うと・・・
更新側が、先にフラグを立てること
閲覧側は、閲覧フラグを+1した後に、もう一度更新フラグを確認することで
+1する前に更新プログラムが走ってしまった場合でも閲覧を待機することが出来るんです。
で、次
「同時に更新が出来ないようにすること」
更新者と閲覧者が、衝突しないようにするのは、それぞれが別々のフラグを利用することで、牽制をするためです。
では、同じ更新者が複数居た場合はどうなるでしょうか?
全く同じプログラムが走るため、違うフラグを利用することは不可能です。
また、複数データを更新しようとした人がいた場合、更新者が同一の場合もあり、アカウントのチェックなどでも不可能です。
更新時の衝突を防ぐ方法は、まぁflockとかでも可能ですが・・・根本的な問題として、主データの登録(insert)時に、そのプライマリキーを取得する事で可能です。
更新を同時に実行しないようにするのではなく、プライマリキーを利用することで、同じ所を更新しないようにすればいいわけです。
でもこれ、追加の場合です。
修正の場合、どうしたらいいのでしょうか?
2カ所から同時に修正ほどばからしい物はありません。
何せ、後から修正した方が優先されるに決まっているんですから、
まぁ、根本的に、同時実行は防がないとダメですね。
単純にflockを使おうと思います。 |
閉じる
|
|
|
|
|
|
no prev page |
1/1ページ(1件) |
no next page |
|