Is the spring TransactionTemplate and SimpleJdbcTemplate thread-safe?

前端 未结 3 1220
暖寄归人
暖寄归人 2021-01-12 11:57

I am currently dealing with code where there is a singleton which is used by many threads and has no state except two fields for a TransactionTemplate and a SimpleJdbcTempla

相关标签:
3条回答
  • 2021-01-12 12:08

    The SimpleJdbcTemplate just wraps a JdbcTemplate, so it's thread-safe, as is the TransactionTemplate.

    0 讨论(0)
  • 2021-01-12 12:09

    TransactionalTemplate is thread safe.

    Finally, instances of the TransactionTemplate class are thread-safe, in that instances do not maintain any conversational state. TransactionTemplate instances do, however, maintain configuration state. So, while a number of classes may share a single instance of a TransactionTemplate, if a class needs to use a TransactionTemplate with different settings (for example, a different isolation level), you need to create two distinct TransactionTemplate instances.

    See https://docs.spring.io/spring/docs/5.2.3.RELEASE/spring-framework-reference/data-access.html#tx-prog-template-settings

    SimpleJdbcTemplate is deprecated. See https://docs.spring.io/autorepo/docs/spring/4.1.3.RELEASE/javadoc-api/index.html?org/springframework/jdbc/core/simple/SimpleJdbcTemplate.html

    0 讨论(0)
  • 2021-01-12 12:16

    Actualy not. See source code for proof. At minimum TransactionTemplate has non final member transactionManager that may be not visible to already created threads. Moreover it derives all non final and publicaly mutable members from DefaultTransactionDefinition.

    In reality dynamic containers (like OSGI) under load you can get NPE on usage of transaction manager inside TransactionTemplate. Especialy if you create TransactionTemplate itself (not by Spring context). It is because working threads (e.g. web request processors) already created and warm (has own thread bound CPU cache). When new TransactionTemplate is created in init thread there are no memory barrier executed to flush thread bound (or CPU core bound) cache. In very rare cases members of newly created TransactionTemplate's may be not visible to 'old' threads.

    We are hit by analogios (not exactly with TransactionTemplate but with RetryTemplate) error on production after hot update of running web service. Need to say that we are not see such error in case of Spring Context created instances, may be because of global sync performed on context initialization.

    Nearly all Spring template classes are mutable and has no explicit synchronization inside. Why documentation say that it is thread save I don't understand.

    You may partialy protect themself by making final the field in own class that contains reference to *Template because of that statement in JMM (see attached link): "In addition, the visible values for any other object or array referenced by those final fields will be at least as up-to-date as the final fields."

    In that case if you are not change state of *Template instance it is "thread safe". Not by class design itself but by specific usage and JMM properties.

    See that question and java memory model on final .

    0 讨论(0)
提交回复
热议问题