実稼働システムで例外がポップアップするという問題がありますが、誰が例外を引き起こしているのかについての良い情報がありません。個人のユーザー名は tomcat セッションに変数として格納されており、明らかにdoPost
ordoGet
メソッドでアクセスできますが、その情報を各ビジネス オブジェクトにパラメーターとして渡さない限り、セッションにアクセスすることはできません。 . 明らかな理由から、ログ メッセージにユーザー名を追加して、何が起こっているのかを把握したいと思います。
だから私の解決策は、このようなことをすることです
public class ExceptionUtil {
private ExceptionUtil() { } // no instantiation
private static final ThreadLocal<String> local = new ThreadLocal<String>();
public static void set(String user) { local.set(user); }
public static String get() { return local.get(); }
}
次に、投稿/取得で、これを行うことができます
String username = request.getSession().getAttribute("username");
ExceptionUtil.set(username);
次に、私の例外では、これを行う可能性があります(不自然な、悪い習慣の例)
catch(SQLException e) {
logger.error(ExceptionUtil.get() + " did something dumb in sql", e);
throw e;
}
私が懸念している唯一の問題は、Tomcat が私のスレッドをどのように管理するかということです。彼らがスレッドを保持するとどうなりますか?彼らは持続しますか?ThreadLocal 値も保持されますか? String だけでなく ThreadLocal に Session 全体を格納していた場合、重大なメモリ リークが発生する可能性があります。また、誰かが複数のリクエストに対して永続化されたスレッドのユーザー名/セッションを再設定するのを忘れた (または完了時にクリアするのを忘れた) 場合、そこに古いデータが存在する可能性があることも意味します。
私の皮肉を呼んでください、しかし私はプログラムの正確さのために何かをすることを忘れないでプログラマーに頼る必要はありません (特に私自身!)。自分のコードをばか証明できるなら、そうしたいです。これは、Tomcat がスレッドをどのように使用するかをよりよく理解することを意味します。
したがって、一文形式の質問は次のとおりです。
Tomcat (7.0.27) で実行されている webapp で ThreadLocal を使用すると、Thread が複数の要求に使用され、以前の要求からのデータが永続化されるリスクがありますか?
「Tomcat/ThreadLocal のシェナニガン」の正確な質問には答えていませんが、ロギング目的でセッション変数にエレガントにアクセスできる代替ソリューションを受け入れることに注意してください。また、私のソリューションの潜在的な落とし穴についてのコメントも受け付けています。解決しなければならないビジネス上の問題がありますが、解決策は 1 つではありません。私の製品システムで誰が例外を引き起こし続けているのか知りたいだけです:)