代码之家  ›  专栏  ›  技术社区  ›  We are Borg

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

  •  0
  • We are Borg  · 技术社区  · 6 年前

    我正在开发一个spring mvc应用程序,其中为不同类型的任务定义了两个数据源。目前,在从xml迁移到java的过程中,我偶然发现了一个需要添加一个新的 HibernateTransactionManager 对象 @Transactional 工作。对于两个不同的数据源,我有两个单独的 SessionFactory 实例。但是,当我试图用另一个数据源创建HiBeNeTeTraceMaungMeor的另一个实例时,我得到了一个非唯一的异常。

    对于发布的配置,是否需要第二个HiBiTeNeTraceAcon管理器实例,或者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实例。现在,我已经注释了需要扩展sessionfactory的dao层方法 secondary_tx ,但不起作用。谢谢您。-)

    1 回复  |  直到 6 年前
        1
  •  1
  •   Yati Sawhney    6 年前

    你问题的答案

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

    Java8向前可以在方法上多次注释(只要注释标注为“可重复”)。实现这一点的另一种方法是给出一个自定义注释,它负责一个数据源。

    您得到的异常是因为有两个用于事务管理的合格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(){
    }