2011-07-19 6 views
6

現在、多くのスレッドで使用されているシングルトンが存在し、シングルトンの機能でデータベースにアクセスするために使用されるTransactionTemplateとSimpleJdbcTemplateの2つのフィールド以外の状態はありません。SpringのTransactionTemplateとSimpleJdbcTemplateはスレッドセーフですか?

これは安全ですか、必要なときにいつでも新しいテンプレートを作成する必要がありますか?

答えて

1

実際にはではなく、です。証明のためのソースコードを参照してください。最低限、TransactionTemplateにはトランザクションマネージャの最後のメンバはありませんはすでに作成されたスレッドには表示されません。さらに、DefaultTransactionDefinitionから最終的ではない宣言的なメンバーをすべて派生します。

現実には、動的なコンテナ(OSGIのような)がロードされていると、TransactionTemplate内のトランザクションマネージャの使用に関するNPEを取得できます。 TransactionTemplate自体を作成する場合(Springコンテキストではなく)これは、作業スレッド(例えば、ウェブ要求プロセッサ)が既に作成され、暖かい(自身のスレッドに結合されたCPUキャッシュを有する)ためである。新しいTransactionTemplateがinitスレッドで作成されると、スレッド境界(またはCPUコア境界)キャッシュをフラッシュするためのメモリバリアは実行されません。ごくまれに、新しく作成されたTransactionTemplateのメンバーが '古い'スレッドには見えないことがあります。

実行中のWebサービスの最新のアップデート後に、analogios(正確にはTransactionTemplateではなくRetryTemplateで)エラーが発生します。 Spring Contextで作成されたインスタンスの場合にこのようなエラーが発生することはなく、コンテキストの初期化時に実行されるグローバル同期が原因である可能性があります。

ほぼすべてのSpringテンプレートクラスは変更可能であり、内部では明示的な同期はありません。なぜドキュメントはそれがスレッドの保存であると言うのか分かりません。

JMMのステートメントのため、* Templateへの参照を含む独自のクラスのフィールドをfinalにすることで、部分的に保護することができます(添付のリンクを参照)。それらの最終フィールドは、少なくとも最終フィールドと同じくらい最新のものになるでしょう。

* Templateインスタンスの状態を変更しない場合は、「スレッドセーフ」です。クラス設計そのものではなく、特定の使用法とJMMのプロパティによって決まります。

that questionおよびjava memory model on finalを参照してください。

関連する問題