[quote]Instances of the JdbcTemplate class are threadsafe once configured. This is important because it
means that you can configure a single instance of a JdbcTemplate and then safely inject this shared
reference into multiple DAOs (or repositories). The JdbcTemplate is stateful, in that it maintains a
reference to a DataSource, but this state is not conversational state.[/quote]
上面的文字摘自spring reference.大意是说jdbcTemplate类本身是线程安全的,但是他本身又是有状态的,spring上下文中它有可以是单例的,不是很清楚它内部是怎么在多线程环境中保持线程安全的。因为他底层的datasource是有状态的,也就是说我不是很清楚jdbcTemplate是怎么在多线程环境中跟datasource交互的。请强人指教,谢谢!!!
恩,以前依照源代码为准,我前面是臆想
JdbcTemplate其实是JDBC的封装,包括了捕获异常、SQL执行、结果转换等。因为是设计模式里面的模版模式,所以叫做xxxTemplate
datasource是更底层的调用,datasource是java.sql的直接实现类,这里你可以实现带链接池的connection或者其它,一般来说,我们的datasource只指向一个数据库,一个数据库只有一个datasource,这样就能方便的管理这个数据库的链接,链接池的个数等等
你可以想像,每一个次的http请求,都是不同的线程,每一次http请求,都几乎会调用数据库,那么通过jdbctemplate调用数据库肯定需要线程安全(其实这个不难,无状态即可,无共享变量),因为datasource只有一个(因为他要管理所有的链接池,这个数据库都是它来负责管理的),每次,jdbcTemplate从datasource里面获得connection,然后sql语句进去,获得结果返回,通过jdbcTemplate直接转化为你自己的结果,就好了,最后jdbctemplate关闭链接池(其实是送回datasource)。
线程安全主要在
org.springframework.transaction.support.TransactionSynchronizationManager中,使用ThreadLocal来保证线程安全
TransactionSynchronizationManager类中声明了:
[code="java"]
private static final ThreadLocal resources =
new NamedThreadLocal("Transactional resources");
private static final ThreadLocal synchronizations =
new NamedThreadLocal("Transaction synchronizations");
private static final ThreadLocal currentTransactionName =
new NamedThreadLocal("Current transaction name");
private static final ThreadLocal currentTransactionReadOnly =
new NamedThreadLocal("Current transaction read-only status");
private static final ThreadLocal currentTransactionIsolationLevel =
new NamedThreadLocal("Current transaction isolation level");
private static final ThreadLocal actualTransactionActive =
new NamedThreadLocal("Actual transaction active");
[/code]
看看源代码就会很清楚了
JdbcTemplate类的实例是线程安全的实例。这一点非常重要,正因为如此,你可以配置一个简单的JdbcTemplate实例,并将这个“共享的”、“安全的”实例注入到不同的DAO类中去。 另外, JdbcTemplate 是有状态的,因为他所维护的DataSource 实例是有状态的,但是这种状态是无法变化的。
一旦JdbcTemplate被创建,他是一个线程安全的对象。 一个你需要创建多次JdbcTemplate实例的理由可能在于,你的应用需要访问多个不同的数据库,从而需要不同的DataSources来创建不同的JdbcTemplates实例。
JdbcTemplate用了ThreadLocal,使各线程能够保持各自独立的一个对象,其实就是一个变量副本,实现了线程安全。