Tomcat ver 9.0.30 HttpSession永続化時のSELECTタイミングの調査

TomcatでPotgreSQLにセッションデータを永続化した時のSELECTタイミング（リクエストの都度最新のDBデータを見に行ってくれるか？）の調査。
背景：某ベンダー製品では、実行スレッド上の最初のHttpSessionアクセス時（getAttribute）にメモリ上にセッションデータがある時はSELECTせず、メモリデータを見に行く挙動となった。この仕様では複数JVM構成環境にて都度最新データをとれないためHttpSessionデータの整合性に問題があるかもしれない。実際に、マルチフレームで異なるサーバーにリクエストを投げる環境下においてアプリケーションエラー（正確にはフレームワーク内部の画面遷移checkエラー）に遭遇した。


Tomcat 9.0.30とPostgreSQL10.6での結果は、サーブレットの最初のgetAttributeで必ずHttpSession永続化DBへSELECTして最新の情報を取得し、以降の同一スレッド上の処理においては二回目以降のgetAttributeではSELECTせず、スレッドローカルのメモリデータを参照するベストな挙動であった。
（某ベンダーの製品はそもそもSELECTしてくれないし、SELECT頻度を変更するパラメータも用意されていない。ベンダーサポート見解も同じであった。）

[設定手順はこちらのリンク参照。バージョン等細かいところは異なるが概ね同じ](https://qiita.com/thashi/items/98bcab8e7d6c32e5632e)

```
2020-02-01 16:34:10.333 JST [25569] LOG:  実行 S_2: SELECT session_id, session_data FROM tomcat_sessions WHERE session_id = $1 AND app_name = $2
2020-02-01 16:34:17.683 JST [25569] LOG:  実行 S_3: DELETE FROM tomcat_sessions WHERE session_id = $1  AND app_name = $2
2020-02-01 16:34:17.687 JST [25569] LOG:  実行 S_4: INSERT INTO tomcat_sessions (session_id, app_name, session_data, valid_session, max_inactive, last_access) VALUES ($1, $2, $3, $4, $5, $6)
2020-02-01 16:34:39.645 JST [30227] LOG:  実行 S_2: SELECT session_id, session_data FROM tomcat_sessions WHERE session_id = $1 AND app_name = $2
2020-02-01 16:34:41.417 JST [30227] LOG:  実行 S_3: DELETE FROM tomcat_sessions WHERE session_id = $1  AND app_name = $2
2020-02-01 16:34:41.420 JST [30227] LOG:  実行 S_4: INSERT INTO tomcat_sessions (session_id, app_name, session_data, valid_session, max_inactive, last_access) VALUES ($1, $2, $3, $4, $5, $6)
2020-02-01 16:34:53.177 JST [25569] LOG:  実行 S_2: SELECT session_id, session_data FROM tomcat_sessions WHERE session_id = $1 AND app_name = $2
2020-02-01 16:34:57.719 JST [25569] LOG:  実行 S_3: DELETE FROM tomcat_sessions WHERE session_id = $1  AND app_name = $2
2020-02-01 16:34:57.722 JST [25569] LOG:  実行 S_4: INSERT INTO tomcat_sessions (session_id, app_name, session_data, valid_session, max_inactive, last_access) VALUES ($1, $2, $3, $4, $5, $6)
2020-02-01 16:35:32.506 JST [30227] LOG:  実行 S_2: SELECT session_id, session_data FROM tomcat_sessions WHERE session_id = $1 AND app_name = $2
2020-02-01 16:35:41.490 JST [30227] LOG:  実行 S_3: DELETE FROM tomcat_sessions WHERE session_id = $1  AND app_name = $2
2020-02-01 16:35:41.493 JST [30227] LOG:  実行 S_4: INSERT INTO tomcat_sessions (session_id, app_name, session_data, valid_session, max_inactive, last_access) VALUES ($1, $2, $3, $4, $5, $6)
2020-02-01 16:36:09.184 JST [25569] LOG:  実行 S_2: SELECT session_id, session_data FROM tomcat_sessions WHERE session_id = $1 AND app_name = $2
2020-02-01 16:36:15.999 JST [30227] LOG:  実行 S_2: SELECT session_id, session_data FROM tomcat_sessions WHERE session_id = $1 AND app_name = $2
2020-02-01 16:36:17.825 JST [25569] LOG:  実行 S_3: DELETE FROM tomcat_sessions WHERE session_id = $1  AND app_name = $2
2020-02-01 16:36:17.830 JST [25569] LOG:  実行 S_4: INSERT INTO tomcat_sessions (session_id, app_name, session_data, valid_session, max_inactive, last_access) VALUES ($1, $2, $3, $4, $5, $6)
2020-02-01 16:36:18.823 JST [25569] LOG:  実行 S_2: SELECT session_id, session_data FROM tomcat_sessions WHERE session_id = $1 AND app_name = $2
2020-02-01 16:36:21.534 JST [30227] LOG:  実行 S_3: DELETE FROM tomcat_sessions WHERE session_id = $1  AND app_name = $2
2020-02-01 16:36:21.535 JST [30227] LOG:  実行 S_4: INSERT INTO tomcat_sessions (session_id, app_name, session_data, valid_session, max_inactive, last_access) VALUES ($1, $2, $3, $4, $5, $6)
2020-02-01 16:36:27.838 JST [25569] LOG:  実行 S_3: DELETE FROM tomcat_sessions WHERE session_id = $1  AND app_name = $2
2020-02-01 16:36:27.840 JST [25569] LOG:  実行 S_4: INSERT INTO tomcat_sessions (session_id, app_name, session_data, valid_session, max_inactive, last_access) VALUES ($1, $2, $3, $4, $5, $6)
2020-02-01 16:36:49.961 JST [30227] LOG:  実行 S_2: SELECT session_id, session_data FROM tomcat_sessions WHERE session_id = $1 AND app_name = $2
2020-02-01 16:36:51.562 JST [30227] LOG:  実行 S_3: DELETE FROM tomcat_sessions WHERE session_id = $1  AND app_name = $2
2020-02-01 16:36:51.563 JST [30227] LOG:  実行 S_4: INSERT INTO tomcat_sessions (session_id, app_name, session_data, valid_session, max_inactive, last_access) VALUES ($1, $2, $3, $4, $5, $6)

```

がPostgreSQLの監査ログ（/var/lib/pgsql/data/logを適宜grepした結果）
getAttribute→setAttribute（session nullの時のみ）→getAttributeするだけの単純プログラム
delete insertはServletの最後に見えていた。セッションの内部タイムスタンプ更新とHttpSession同期目的。updateしないのは特定DBを意識した実装と予想。

PostgreSQLの設定コマンド

```
tomcat=# alter database tomcat set log_statement = 'all';
```

/var/lib/pgsql/data/postgresql.confの断片

```
log_destination = 'stderr'              
logging_collector = on                  
log_directory = 'log'                   
log_filename = 'postgresql-%a.log'      
#log_file_mode = 0600                   
log_truncate_on_rotation = on           
log_rotation_age = 1d                   
log_rotation_size = 0                   
syslog_facility = 'LOCAL0'
syslog_ident = 'postgres'
syslog_sequence_numbers = on
syslog_split_messages = on
```