質問: ### やりたいこと Webシステムを作っています。構成は以下の通りです。 * Tomcat * terasoluna(strutsベース) 今、システム稼動中にシステムの設定値を変えたいです。 たとえば、「表示できる最大件数」などです。 開発機と本番環境でデータ量やスペックが異なります。 したがって、システムを稼動した後、しばらく様子を見てから最適な値に変更したいです。 ### 質問 システムの設定値は、どこに設定すべきでしょうか? 内容的にはsystem.propertiesに設定すべきだと思っています。 しかし、system.propertiesを変更したらTomcatを再起動が必要なので、この方法は「却下」です。 現在は、データベースに設定しています。 データベースの値を変更しても、Tomcatの再起動は不要だからです。 以下のようなシステム用のテーブルに、値を入れています。 ``` CREATE TABLE type ( key VARCHAR(20) value VARCHAR(40), CONSTRAINT PRIMARY KEY (key) ) ``` ただ、この方法は「データベース本来の使い方ではない」ような気がしていて、もやもやを感じています。 うまく説明はできませんが、「値を保持しておくだけなら、データベースである必要がない」というもやもやです。 最適な方法があれば教えていただきたいです。
回答: Webシステムで稼働中に設定を変更するならば、データベースで保持する方法が最適だと思います。 理由はデータベース(DBMS)にあるトランザクション&ロック機構です。 Webシステムは不特定多数のユーザが同時並行でアクセスしてくるものです。 system.propertiesのようなファイルベースの設定をシステム停止なしで反映しようとすると、設定ファイルの更新中にアクセスされないようにファイルロックなど同期処理の制御を行う必要があります。 もし、設定ファイルの内容を変更するのではなく、設定済みのファイルに差し替えるようなことを考えているとすると、設定ファイルが入れ替わるにあたり一時的にファイルが存在しなくなる状況が発生することも考慮しなければなりません。 ファイルベースの設定でシステム稼働したまま設定に変更をかけることは、制御がかなり難しいです。 データベースであれば、ファイルベースにおいてハードルとなる上記の課題はDBMSのロックの機構がやってくれます。 データベースならば、"設定を変更している最中にWebシステムを利用しているユーザ"もある程度はカバーできます。トランザクション機構を用いることで、設定の変更をcommitで確定するまでは、変更前の設定を前述のユーザは使い続けることができます。 別の方法としては、Tomcatのホットデプロイ機構を使う方法もあります。 設定はjarファイル(まはたclassファイル)にしておき、これを差し替え、ホットデプロイでTomcatにロードさせ設定変更を反映する方法です。 データベースよりも手っ取り早いですが、いささか強引な手法ではあるかなと思います。 上記のように書きましたが、本番環境において停止が可能なシステムであれば、停止して変更を反映することをお勧めします。停止が不可能なシステムならば、クラスタ構成にするのが一般的です。 課題は"設定を変更にあたり変更前から変更後に渡ってWebシステムを利用しているユーザ"の扱いです。 このユーザが存在する状態で設定を変更すると、そのユーザにとってはシステムの挙動が突然変わることになります。 例えば「次ページ遷移で元は100件単位だったのが、次ページ遷移したら突然10件単位に変わってしまった。」なんていう風に挙動が変わります。 事情を知らないユーザにとって場合によってはやってもいない変化が突然発生するので、不具合のように見えます。 設定変更前には変更をするアナウンスを行うなど、ユーザに配慮できると良いですね。