Spring的TransactionTemplate和SimpleJdbcTemplate是线程安全的吗?

我目前正在处理代码,其中有一个单例,它被许multithreading使用,并且除了用于单例函数访问数据库的TransactionTemplate和SimpleJdbcTemplate的两个字段之外没有任何状态。

这是安全还是我应该在需要的时候创建一个新模板?

SimpleJdbcTemplate只包装一个JdbcTemplate,因此它是线程安全的 ,就像TransactionTemplate一样 。

实际上没有 。 请参阅源代码以获取certificate。 至少TransactionTemplate具有非最终成员transactionManager ,可能对已创建的线程不可见 。 此外,它从DefaultTransactionDefinition派生所有非final和publicaly可变成员。

实际上,在加载时,动态容器(如OSGI)可以在TransactionTemplate内使用事务管理器时获得NPE。 特别是如果您自己创建TransactionTemplate(而不是通过Spring上下文)。 这是因为工作线程(例如Web请求处理器)已经创建并且是热的(具有自己的线程绑定CPU缓存)。 在init线程中创建新的TransactionTemplate时,没有执行内存屏障来刷新线程绑定(或CPU核心绑定)缓存。 在极少数情况下,新创建的TransactionTemplate的成员可能对“旧”线程不可见。

在运行Web服务的热更新后,我们受到模拟(不完全是TransactionTemplate但使用RetryTemplate)的错误。 需要说明的是,在Spring Context创建实例的情况下我们没有看到这样的错误,可能是因为在上下文初始化时执行了全局同步。

几乎所有Spring模板类都是可变的,并且内部没有明确的同步。 为什么文档说它是线程保存我不明白。

您可以通过在自己的类中创建最终字段来保护自己,因为JMM中的该语句引用了包含* Template的引用(请参阅附件链接):“此外,这些最终字段引用的任何其他对象或数组的可见值将至少与最终领域一样最新。“

在这种情况下,如果您没有更改* Template实例的状态,那么它是“线程安全的”。 不是通过类设计本身,而是通过特定用法和JMM属性。

最后看到那个问题和java内存模型 。