Является ли пружина TransactionTemplate и SimpleJdbcTemplate поточно-ориентированной? - PullRequest
7 голосов
/ 19 июля 2011

В настоящее время я имею дело с кодом, в котором есть синглтон, который используется многими потоками и не имеет состояния, кроме двух полей для TransactionTemplate и SimpleJdbcTemplate, которые используются в функциях синглтона для доступа к базе данных.

Безопасно ли это, или я должен создать новый шаблон, когда он мне нужен?

Ответы [ 2 ]

16 голосов
/ 19 июля 2011

SimpleJdbcTemplate просто оборачивает JdbcTemplate, поэтому это потокобезопасное , как и TransactionTemplate .

2 голосов
/ 19 декабря 2014

На самом деле не .Смотрите исходный код для доказательства.Как минимум TransactionTemplate имеет не окончательный элемент TransactionsManager , который может быть невидимым для уже созданных потоков.Более того, он получает все не финальные и публикуемые изменяемые члены из DefaultTransactionDefinition.

В реальности динамические контейнеры (например, OSGI) под нагрузкой вы можете получить NPE при использовании диспетчера транзакций внутри TransactionTemplate.Особенно, если вы создаете сам TransactionTemplate (не в контексте Spring).Это связано с тем, что рабочие потоки (например, процессоры веб-запросов) уже созданы и работают (имеет собственный кэш-память ЦП).При создании нового TransactionTemplate в потоке инициализации не выполняется барьер памяти для очистки кэша, привязанного к потоку (или ядру процессора).В очень редких случаях члены вновь созданных TransactionTemplate могут быть невидимы для «старых» потоков.

Мы сталкиваемся с ошибкой аналога (не только с TransactionTemplate, но с RetryTemplate) при производстве после горячего обновления запущенного веб-сервиса.Нужно сказать, что мы не видим такой ошибки в случае экземпляров, созданных Spring Context, возможно, из-за глобальной синхронизации, выполняемой при инициализации контекста.

Почти все классы шаблонов Spring являются изменяемыми и не имеют явной синхронизации внутри.Почему в документации сказано, что это потокобезопасность, я не понимаю.

Вы можете частично защитить себя, сделав final поле в своем классе, содержащее ссылку на * Template, из-за этого оператора в JMM (см. Прикрепленную ссылку): "Кроме того, видимые значения для любого другого объекта или массива, на которые ссылаются эти последние поля, будут как минимум такими же актуальными, как и последние поля."

В этом случае, если вы не измените состояние* Шаблон экземпляра это "потокобезопасный".Не самим классом, а конкретным использованием и свойствами JMM.

См. этот вопрос и модель памяти Java в окончательном варианте .

...