繁体   English   中英

Spring:我需要为2个数据源定义单独的TransactionManager吗?

[英]Spring : Do I require to define separate TransactionManager for 2 data sources?

我正在开发一个Spring-MVC应用程序,在该应用程序中我为不同类型的任务定义了2个数据源。 当前,在从XML到Java的迁移过程中,我偶然发现了为@Transactional添加新的HibernateTransactionManager对象的要求。 对于2个不同的数据源,我有2个单独的SessionFactory实例。 但是,当我尝试使用辅助数据源创建另一个HibernateTransactionManager实例时,出现了一个非唯一异常。

我要发布的配置是否需要辅助HibernateTransactionManager实例,还是1个就足够了? 如果需要,如何创建一个? 谢谢。

错误日志:

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: primary_tx,extended_tx
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:368)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:367)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:271)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springfram

WebConfig.java:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.ourapp.spring"})
@EnableTransactionManagement
@EnableCaching
public class WebConfig extends WebMvcConfigurerAdapter {


 @Bean(name="primary_tx")
    public HibernateTransactionManager getPrimaryTransactionManager() throws IOException {
        HibernateTransactionManager txName= new HibernateTransactionManager();
        txName.setSessionFactory(sessionFactory().getObject());
        return txName;
    }

    @Bean(name="extended_tx")
    public HibernateTransactionManager txName() throws IOException {
        HibernateTransactionManager txName= new HibernateTransactionManager();
        txName.setSessionFactory(getExtendedSessionFactory().getObject());
        return txName;
    }

    @Bean
    @Qualifier("sessionFactory_origin")
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(new DataSourceConfig().primaryDataSource());
        sessionFactory.setPackagesToScan("com.ourapp.spring");
        return sessionFactory;
    }

     @Bean
@Qualifier("sessionFactory_extended")
public LocalSessionFactoryBean getExtendedSessionFactory() {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(new DataSourceConfig_Extended().secondaryDataSource());
    sessionFactory.setPackagesToScan("com.ourapp.spring");
    return sessionFactory;
}
}

典型的服务层方法:

@Service
@Transactional("primary_tx")
public class ChatRoomMembersServiceImpl implements ChatRoomMembersService{


   private final ChatRoomMembersDAO chatRoomMembersDAO;

    @Autowired
    public ChatRoomMembersServiceImpl(ChatRoomMembersDAO chatRoomMembersDAO){
        this.chatRoomMembersDAO = chatRoomMembersDAO;
    }
}

典型的DAO层方法:

@Repository
@Transactional("primary_tx")
public class ChatRoomMembersDAOImpl implements ChatRoomMembersDAO{

    @Autowired
    @Qualifier(value = "sessionFactory_origin")
    private  SessionFactory sessionFactory;

    @Autowired
    @Qualifier(value = "sessionFactory_extended")
    private  SessionFactory sessionFactory_extended;

}

现在,每当需要时,我指的是扩展的SessionFactory实例。 现在,我已经注释了DAO层方法,需要使用secondary_tx扩展sessionFactory,但是它不起作用。 谢谢。 :-)

您问题的答案

我是否需要为2个数据源定义单独的TransactionManager?

YES

从Java8开始,您可以在一个方法上多次具有相同的批注(前提是批注标记为@Repeatable)。 实现此目的的另一种方法是提供自定义注释,该注释将处理数据源之一。

您得到的异常是因为有两个用于事务管理的合格Bean。 您需要一个限定词。

代替:

@Bean(name="primary_tx")
    public HibernateTransactionManager getPrimaryTransactionManager() throws IOException {
        HibernateTransactionManager txName= new HibernateTransactionManager();
        txName.setSessionFactory(sessionFactory().getObject());
        return txName;
    }

采用

@Bean @Qualifier("primary_tx")

    public HibernateTransactionManager getPrimaryTransactionManager() throws IOException {
        HibernateTransactionManager txName= new HibernateTransactionManager();
        txName.setSessionFactory(sessionFactory().getObject());
        return txName;
    }

现在,假设您要使我的方法m1中的事务成为原子事务。 以下是您需要的

@Transactional("primary_tx")
public void m1(){
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM