我有两个春季交易经理。
问题是我使用txManager2执行某些操作,但是以某种方式使用txManager1而不是txManager2,并且数据已提交到DB1而不是DB2。
@Autowired
@Qualifier("common-tx")
private PlatformTransactionManager txManager2 ;
@KafkaListener(topics = "${kafka.topic.name}", groupId = "group-1", containerFactory = "customKafkaListenerContainerFactory")
public void topicListener(String message, Acknowledgment ack)
throws InterruptedException, ClassNotFoundException, IOException {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName(domainEvent.getEventId());
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus commonStatus = txManager2 .getTransaction(def);
someService.doSomething();
txManager2 .commit(commonStatus);
ack.acknowledge();
}
在doSomething()
中,我只是保留一个实体,调试后发现,通过Spring数据存储库保存该实体时,事务管理器
invokeWithinTransaction()
的{{1}}中确定是错误的,即选择了txManager1而不是txManager2,这是配置问题还是我遗漏了什么?
txManager1配置:
org.springframework.transaction.interceptor.TransactionAspectSupport
txManager2配置:
@Configuration
@EnableTransactionManagement
@PropertySource(value = {"classpath:application-${spring.profiles.active}.properties"})
@Profile({"development","production","qa"})
@EnableJpaRepositories(basePackages={"xxx.xxx.xxxx"},excludeFilters=@ComponentScan.Filter(type=FilterType.REGEX, pattern="xxx.xxx.xxxx.module2.*"))
public class JPAConfig1 {
@Value("${jndi.name}")
private String jndiName;
@Value("${hibernate.dialect}")
private String hibernateDialect;
@Value("${hibernate.show_sql}")
private String showSql;
@Value("${hibernate.format_sql}")
private String formatSql;
@Value("${hibernate.hbm2ddl.auto}")
private String hiberanteUpdate;
@Value("${javax.persistence.validation.mode}")
private String hibernateValidation;
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactory(MultiTenantConnectionProviderImpl tenantConnection, CurrentTenantIdentifierResolver currentTenantIdentifierResolver)
{
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
emf.setJpaVendorAdapter(vendorAdapter);
emf.setJpaProperties(jpaProperties(tenantConnection, currentTenantIdentifierResolver));
emf.setPackagesToScan(new String[] {"xxx.xxx.xxxx"});
return emf;
}
private Properties jpaProperties(MultiTenantConnectionProviderImpl tenantConnection, CurrentTenantIdentifierResolver currentTenantIdentifierResolver) {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect",hibernateDialect);
properties.setProperty("hibernate.show_sql",showSql);
properties.setProperty("hibernate.format_sql",formatSql);
properties.setProperty("hibernate.hbm2ddl.auto",hiberanteUpdate);
properties.setProperty("javax.persistence.validation.mode",hibernateValidation);
properties.put(Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
properties.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver);
properties.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, tenantConnection);
return properties;
}
@Bean
public CurrentTenantIdentifierResolver getCurrentTenantIdentifierResolver(TenantContext tenantContext) {
return new CurrentTenantIdentifierResolverImpl(tenantContext);
}
@Bean(name="tenantConnection")
public MultiTenantConnectionProviderImpl getMultiTenantConnectionProvider(TenantContext tenantContext) {
return new MultiTenantConnectionProviderImpl(false,tenantContext);
}
@Bean
@Primary
public PlatformTransactionManager transactionManager(EntityManagerFactory factory,ProducerFactory producerFactory){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(factory);
KafkaTransactionManager tm = new KafkaTransactionManager(producerFactory);
return new ChainedKafkaTransactionManager(tm,transactionManager);
}
@Bean
public TenantContext getTenantContext() {
return new TenantContextImpl();
}
}