我观察到与Spring如何处理多个数据源操作有关的看似奇怪的行为,尤其是参与事务同步。
My Spring上下文配置了两个数据源:
1)dataSource1 - MySQL数据库
2)dataSource2 - Apache Impala数据库
两个数据源都配置了jdbc模板。此外,dataSource1配置了事务管理器。 dataSource2没有配置事务管理器(Apache Impala没有设计事务,它恰好通过JDBC连接器公开类似SQL的查询功能)。
我在弹簧批处理应用程序中使用此配置 - dataSource1及其transactionManager设置用于存储与弹簧批处理作业元信息相关的数据。
接下来,我有一个弹出批处理作业配置了一个自定义Tasklet步骤。在这一步中,我通过其jdbc模板访问dataSource2。这就是出现问题的地方 - 令我惊讶的是,与dataSource2的连接开始参与事务同步。
2018-06-06 10:41:08,179 DEBUG [main] org.springframework.jdbc.datasource.DataSourceUtils - Registering transaction synchronization for JDBC Connection
据我所知,在弹出批处理步骤开始时,会启动与dataSource1相关的事务,但是为什么dataSource2无论如何都要参与其中呢?
负面的副作用是,一旦与dataSource2的连接开始参与事务同步,连接就不会在例如jdbcTemplate.execute(...)命令完成。基本上我正在观察的是,只有在外部事务完成时,才会关闭与dataSource2的打开连接。
有没有办法配置Spring上下文和dataSource2不参与事务同步?
配置
<bean id="dataSource1" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<constructor-arg ref="hikariConfig" />
</bean>
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="springHikariCP" />
<property name="dataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" />
...
</bean>
<bean id="dataSource1JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource1"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:dataSource-ref="dataSource1">
<property name="packagesToScan" value="..."/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="sharedCacheMode" value="DISABLE_SELECTIVE"/>
</bean>
<bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="org.apache.hive.jdbc.HiveDriver"/>
...
</bean>
<bean id="dataSource2JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource2"/>
</bean>